OPENJPA-1115 Remaining delimited identifiers support, including pluggable identifier utility. Includes code and test contributions from Dianne Richards.

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@899784 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Jeremy Bauer 2010-01-15 19:38:18 +00:00
parent 7b53696e6e
commit fadd48fe5b
156 changed files with 8953 additions and 2265 deletions

View File

@ -21,6 +21,7 @@ package org.apache.openjpa.jdbc.conf;
import javax.sql.DataSource;
import org.apache.openjpa.conf.OpenJPAConfiguration;
import org.apache.openjpa.jdbc.identifier.DBIdentifierUtil;
import org.apache.openjpa.jdbc.kernel.EagerFetchModes;
import org.apache.openjpa.jdbc.kernel.LRSSizes;
import org.apache.openjpa.jdbc.kernel.UpdateManager;
@ -31,6 +32,7 @@ import org.apache.openjpa.jdbc.schema.SchemaFactory;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.jdbc.sql.SQLFactory;
import org.apache.openjpa.kernel.StoreContext;
import org.apache.openjpa.lib.identifier.IdentifierUtil;
import org.apache.openjpa.lib.jdbc.ConnectionDecorator;
import org.apache.openjpa.lib.jdbc.JDBCEvent;
import org.apache.openjpa.lib.jdbc.JDBCListener;
@ -592,7 +594,7 @@ public interface JDBCConfiguration
* Return the non-enlisted data source to use. If there is a valid
* non-xa connection factory configured, then it will be returned. Its
* default user name and password on calls to
* {@link DataSource#getConnection} will be the specificed connection 2
* {@link DataSource#getConnection} will be the specified connection 2
* user name and password. If those are null and the given context is
* non-null, its user name password will be used instead. If the context
* is null too, then the user name and password used to retrieve the first
@ -602,4 +604,23 @@ public interface JDBCConfiguration
* @see #getDataSource
*/
public DataSource getDataSource2(StoreContext ctx);
/**
* Gets the String constant that matches the {@link IdentifierUtil}
* @return String-based name of the {@link IdentifierUtil}
*/
public String getIdentifierUtil();
/**
* Gets the {@link DBIdentifierUtil}
* @return DBIdentifierUtil
*/
public DBIdentifierUtil getIdentifierUtilInstance();
/**
* Sets the {@link DBIdentifierUtil}
* @param util instance of the identifier utility
*/
public void setIdentifierUtil(DBIdentifierUtil util);
}

View File

@ -24,6 +24,7 @@ import javax.sql.DataSource;
import org.apache.commons.lang.StringUtils;
import org.apache.openjpa.conf.OpenJPAConfigurationImpl;
import org.apache.openjpa.jdbc.identifier.DBIdentifierUtil;
import org.apache.openjpa.jdbc.kernel.BatchingConstraintUpdateManager;
import org.apache.openjpa.jdbc.kernel.BatchingOperationOrderUpdateManager;
import org.apache.openjpa.jdbc.kernel.EagerFetchModes;
@ -47,6 +48,7 @@ import org.apache.openjpa.lib.conf.PluginValue;
import org.apache.openjpa.lib.conf.ProductDerivations;
import org.apache.openjpa.lib.conf.StringListValue;
import org.apache.openjpa.lib.conf.StringValue;
import org.apache.openjpa.lib.identifier.IdentifierUtil;
import org.apache.openjpa.lib.jdbc.ConnectionDecorator;
import org.apache.openjpa.lib.jdbc.DecoratingDataSource;
import org.apache.openjpa.lib.jdbc.JDBCListener;
@ -82,6 +84,7 @@ public class JDBCConfigurationImpl
public ObjectValue mappingDefaultsPlugin;
public PluginValue driverDataSourcePlugin;
public MappingFactoryValue mappingFactoryPlugin;
public ObjectValue identifierUtilPlugin;
// used internally
private String firstUser = null;
@ -331,6 +334,15 @@ public class JDBCConfigurationImpl
finderCachePlugin.setDynamic(true);
finderCachePlugin.setInstantiatingGetter("getFinderCacheInstance");
identifierUtilPlugin = addPlugin("jdbc.IdentifierUtil", true);
aliases = new String[] {
"default", "org.apache.openjpa.jdbc.identifier.DBIdentifierUtilImpl" };
identifierUtilPlugin.setAliases(aliases);
identifierUtilPlugin.setDefault(aliases[0]);
identifierUtilPlugin.setString(aliases[0]);
identifierUtilPlugin.setInstantiatingGetter("getIdentifierUtilInstance");
// this static initializer is to get past a weird
// ClassCircularityError that happens only under IBM's
// JDK 1.3.1 on Linux from within the JRun ClassLoader;
@ -899,4 +911,19 @@ public class JDBCConfigurationImpl
return true;
return false;
}
public String getIdentifierUtil() {
return identifierUtilPlugin.getString();
}
public DBIdentifierUtil getIdentifierUtilInstance() {
if (identifierUtilPlugin.get() == null)
identifierUtilPlugin.instantiate(DBIdentifierUtil.class, this);
return (DBIdentifierUtil) identifierUtilPlugin.get();
}
public void setIdentifierUtil(DBIdentifierUtil util) {
identifierUtilPlugin.set(util);
}
}

View File

@ -0,0 +1,39 @@
/*
* 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.jdbc.identifier;
import org.apache.openjpa.jdbc.identifier.DBIdentifier.DBIdentifierType;
/**
* Default rule for column definition. This rule disables delimiting of
* column definitions. Column definitions can be extremely tricky to
* delimit correctly. Blindly delimiting them causes failures on most
* databases. Where user defined types are concerned, generally they don't
* need to be delimited and if so, they are more appropriately delimited
* when they are specified.
*/
public class ColumnDefIdentifierRule extends DBIdentifierRule {
public ColumnDefIdentifierRule() {
super();
setName(DBIdentifierType.COLUMN_DEFINITION.toString());
// Disable auto delimiting of column definition.
setCanDelimit(false);
}
}

View File

@ -0,0 +1,911 @@
/*
* 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.jdbc.identifier;
import java.io.Serializable;
import org.apache.commons.lang.StringUtils;
import org.apache.openjpa.lib.identifier.Identifier;
import org.apache.openjpa.lib.identifier.IdentifierImpl;
/**
* Encapsulates a database identifier. With a few exceptions, this class is
* intended to treated as immutable.
*/
public class DBIdentifier extends IdentifierImpl implements Cloneable, Identifier, Serializable {
/**
* Database identifier types.
*/
public enum DBIdentifierType {
DEFAULT,
TABLE,
SCHEMA,
CATALOG,
DATABASE,
COLUMN,
COLUMN_DEFINITION,
SEQUENCE,
CONSTRAINT,
INDEX,
FOREIGN_KEY,
CONSTANT,
NULL
}
// Array for quick compound identifier determination. Compound identifiers
// can have multi-part names, such as {schema, table} and should be stored
// as a QualifiedDBIdentifier.
private static boolean _compoundIdentifier[] = new boolean[DBIdentifierType.values().length];
static {
_compoundIdentifier[DBIdentifierType.TABLE.ordinal()] = true;
_compoundIdentifier[DBIdentifierType.COLUMN.ordinal()] = true;
_compoundIdentifier[DBIdentifierType.SEQUENCE.ordinal()] = true;
_compoundIdentifier[DBIdentifierType.CONSTRAINT.ordinal()] = true;
_compoundIdentifier[DBIdentifierType.INDEX.ordinal()] = true;
}
private DBIdentifierType _type = DBIdentifierType.DEFAULT;
/**
* Special NULL indicator for db identifiers.
*/
public static final DBIdentifier NULL = new DBIdentifier(DBIdentifierType.NULL);
// All constructors are protected or private. Static factory operations
// should be used to construct new identifiers.
protected DBIdentifier() {
}
private DBIdentifier(DBIdentifierType type) {
setType(type);
}
protected DBIdentifier(String name, DBIdentifierType type) {
setType(type);
setName(name);
}
protected DBIdentifier(String name, DBIdentifierType type, boolean delimit) {
setType(type);
setName(name, delimit);
}
protected DBIdentifier(String name, boolean delimit) {
setName(name, delimit);
}
/**
* Set the name of the identifier.
*/
public void setName(String name) {
setName(name, false);
}
/**
* Set the name of this identifier based upon a given identifier.
*/
public void setName(DBIdentifier name) {
assertNotNull();
if (DBIdentifier.isNull(name)) {
setNameInternal(null);
setType(name.getType());
return;
}
setNameInternal(name.getNameInternal());
setType(name.getType());
}
/**
* Set the name of the identifier and optionally force delimiting of the identifier.
*/
public void setName(String name, boolean delimit) {
assertNotNull();
// Normalize the name, if necessary. Do not normalize constants or column definitions.
if (DBIdentifierType.CONSTANT != getType() && DBIdentifierType.COLUMN_DEFINITION != getType()) {
if (delimit) {
name = Normalizer.delimit(name, true);
} else {
name = Normalizer.normalizeString(name);
}
}
super.setName(name);
}
/**
* Set the type of the identifier
* @param type
*/
protected void setType(DBIdentifierType type) {
_type = type;
}
/**
* Get the identifier type
* @return the identifier type
*/
public DBIdentifierType getType() {
return _type;
}
/**
* Splits a string delimited by the specified delimiter of a given name type
* into an array of DBIdentifier objects.
* Example: COL1|"COL 2"|COL3 delim=| --> DBIdentifier[]{ COL1, "COL 2", COL3 }
* @param name
* @param id
* @param delim
* @return
*/
public static DBIdentifier[] split(String name, DBIdentifierType id, String delim) {
if (!Normalizer.canSplit(name, delim)) {
return new DBIdentifier[] { new DBIdentifier(name, id) };
}
String[] names = Normalizer.splitName(name, delim);
if (names.length == 0) {
return new DBIdentifier[] { };
}
DBIdentifier[] sNames = new DBIdentifier[names.length];
for (int i = 0; i < names.length ; i++) {
sNames[i] = new DBIdentifier(names[i], id);
}
return sNames;
}
/**
* Joins the list of identifiers using the appropriate delimiters and
* returns a string based identifier.
* @param resultId
* @param names
* @return
*/
public static String join(DBIdentifier...names) {
if (names == null || names.length == 0) {
return null;
}
String[] strNames = new String[names.length];
for (int i = 0; i < names.length; i++) {
strNames[i] = names[i].getNameInternal();
}
return Normalizer.joinNames(strNames);
}
/**
* Splits a given DBIdentifier into multiple DBIdentifiers. Uses the base name
* type and heuristics to determine the types and placement of the resulting
* components.
* @param name
* @return
*/
public static DBIdentifier[] split(DBIdentifierType resultType, String name) {
String[] names = Normalizer.splitName(name);
switch (names.length) {
case 2:
return getTwoPartIdentifier(names, resultType);
case 3:
return getThreePartIdentifier(names, resultType);
case 4:
return getFourPartIdentifier(names, resultType);
default:
return new DBIdentifier[] { new DBIdentifier(name, resultType) };
}
}
/*
* Returns a two-part identifier based upon the base identifier type.
*/
private static DBIdentifier[] getTwoPartIdentifier(String[] names, DBIdentifierType baseId) {
DBIdentifier[] sNames = new DBIdentifier[2];
DBIdentifierType id0 = DBIdentifierType.DEFAULT;
DBIdentifierType id1 = baseId;
if (baseId != DBIdentifierType.COLUMN &&
baseId != DBIdentifierType.SCHEMA) {
id0 = DBIdentifierType.SCHEMA;
}
else if (baseId == DBIdentifierType.COLUMN) {
// Length 2, base name column
id0 = DBIdentifierType.TABLE;
}
else if (baseId == DBIdentifierType.SCHEMA) {
id0 = DBIdentifierType.DATABASE;
}
sNames[0] = new DBIdentifier(names[0], id0);
sNames[1] = new DBIdentifier(names[1], id1);
return sNames;
}
/*
* Returns a three-part identifier based upon the base identifier type.
*/
private static DBIdentifier[] getThreePartIdentifier(String[] names, DBIdentifierType baseId) {
DBIdentifier[] sNames = new DBIdentifier[3];
DBIdentifierType id0 = DBIdentifierType.DEFAULT;
DBIdentifierType id1 = DBIdentifierType.DEFAULT;
DBIdentifierType id2 = baseId;
if (baseId != DBIdentifierType.SCHEMA &&
baseId != DBIdentifierType.COLUMN) {
id0 = DBIdentifierType.DATABASE;
id1 = DBIdentifierType.SCHEMA;
}
else if (baseId == DBIdentifierType.COLUMN) {
// Length 2, base name column
id0 = DBIdentifierType.SCHEMA;
id1 = DBIdentifierType.TABLE;
}
sNames[0] = new DBIdentifier(names[0], id0);
sNames[1] = new DBIdentifier(names[1], id1);
sNames[2] = new DBIdentifier(names[2], id2);
return sNames;
}
/*
* Returns a four-part identifier based upon the base identifier type.
*/
private static DBIdentifier[] getFourPartIdentifier(String[] names, DBIdentifierType baseId) {
DBIdentifier[] sNames = new DBIdentifier[4];
DBIdentifierType id0 = DBIdentifierType.DEFAULT;
DBIdentifierType id1 = DBIdentifierType.DEFAULT;
DBIdentifierType id2 = DBIdentifierType.DEFAULT;
DBIdentifierType id3 = baseId;
if (baseId == DBIdentifierType.COLUMN) {
id0 = DBIdentifierType.DATABASE;
id1 = DBIdentifierType.SCHEMA;
id2 = DBIdentifierType.TABLE;
}
sNames[0] = new DBIdentifier(names[0], id0);
sNames[1] = new DBIdentifier(names[1], id1);
sNames[2] = new DBIdentifier(names[2], id2);
sNames[3] = new DBIdentifier(names[3], id3);
return sNames;
}
/**
* Returns true if the identifier is null or the name is null or empty.
* @param name
* @return
*/
public static boolean isEmpty(DBIdentifier name) {
if (isNull(name)) {
return true;
}
return StringUtils.isEmpty(name.getName());
}
/**
* Returns true if the identifier is null.
* @param name
* @return
*/
public static boolean isNull(DBIdentifier name) {
return (name == null || name.getType() == DBIdentifierType.NULL);
}
/**
* Clones an identifier using deep copy.
*/
public DBIdentifier clone() {
DBIdentifier sName = new DBIdentifier();
sName.setNameInternal(getNameInternal());
sName.setType(getType());
return sName;
}
/*
* Internal method to set the base name and avoid normalizing an already
* normalized name.
* @param name
*/
private void setNameInternal(String name) {
super.setName(name);
}
/*
* Internal method to get the base name.
* normalized name.
* @param name
*/
private String getNameInternal() {
return super.getName();
}
/**
* Returns a copy of an identifier with name trimmed to null.
* @param name
* @return
*/
public static DBIdentifier trimToNull(DBIdentifier name) {
if (DBIdentifier.isNull(name)) {
return name;
}
DBIdentifier sName = name.clone();
sName.setNameInternal(StringUtils.trimToNull(sName.getNameInternal()));
return sName;
}
/**
* Equality operation for identifiers. Supports comparison with strings
* and objects of this type.
*/
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (obj == this) {
return true;
}
if (obj instanceof DBIdentifier) {
DBIdentifier sName = (DBIdentifier)obj;
return this.equals(sName, false);
} else if (obj instanceof String) {
return obj.equals(this.getNameInternal());
}
throw new IllegalArgumentException("Unsupported type comparison: " + obj.getClass().getName());
}
/**
* Returns true if this object is NULL or has a null name component.
* @return
*/
public boolean isNull() {
return (_type == DBIdentifierType.NULL || getName() == null);
}
/**
* Comparison operator for identifiers.
*/
public int compareTo(Identifier o) {
if (o instanceof DBIdentifier) {
if (this == DBIdentifier.NULL && (o == null || o == DBIdentifier.NULL)) {
return 0;
}
if (this == DBIdentifier.NULL)
return 1;
if (o == null || o == DBIdentifier.NULL)
return -1;
}
return super.compareTo(o);
}
/**
* Converts the provided set of names to an array of identifiers of the
* provided type
* @param columnNames
* @param id
* @return
*/
public static DBIdentifier[] toArray(String[] columnNames, DBIdentifierType id) {
return toArray(columnNames, id, false);
}
/**
* Converts the provided set of names to an array of identifiers of the
* provided type, optionally delimiting the names.
* @param columnNames
* @param id
* @return
*/
public static DBIdentifier[] toArray(String[] names, DBIdentifierType id, boolean delimit) {
if (names == null) {
return null;
}
DBIdentifier[] sNames = new DBIdentifier[names.length];
for (int i = 0; i < names.length; i++) {
sNames[i] = new DBIdentifier(names[i], id, delimit);
}
return sNames;
}
/**
* Returns a string array of names based upon the provided set of identifiers.
* @param sNames
* @return
*/
public static String[] toStringArray(DBIdentifier[] sNames) {
if (sNames == null) {
return null;
}
String[] names = new String[sNames.length];
for (int i = 0; i < sNames.length; i++) {
names[i] = sNames[i].getName();
}
return names;
}
/**
* Constructs a new identifier of type Catalog.
*/
public static DBIdentifier newCatalog(String name) {
return newIdentifier(name, DBIdentifierType.CATALOG);
}
/**
* Constructs a new identifier of type Catalog ,optionally delimiting
* the name.
*/
public static DBIdentifier newCatalog(String name, boolean delimit) {
return newIdentifier(name, DBIdentifierType.CATALOG, false, delimit);
}
/**
* Constructs a new identifier of type Table.
*/
public static DBIdentifier newTable(String name) {
return newIdentifier(name, DBIdentifierType.TABLE);
}
/**
* Constructs a new identifier of type Table, optionally delimiting
* the name.
*/
public static DBIdentifier newTable(String name, boolean delimit) {
return newIdentifier(name, DBIdentifierType.TABLE, false, delimit);
}
/**
* Constructs a new identifier of type Column.
*/
public static DBIdentifier newColumn(String name) {
return newIdentifier(name, DBIdentifierType.COLUMN);
}
/**
* Constructs a new identifier of type Column,optionally delimiting
* the name.
*/
public static DBIdentifier newColumn(String name, boolean delimit) {
return newIdentifier(name, DBIdentifierType.COLUMN, false, delimit);
}
/**
* Constructs a new identifier of type Schema.
*/
public static DBIdentifier newSchema(String name) {
return newIdentifier(name, DBIdentifierType.SCHEMA);
}
/**
* Constructs a new identifier of type Schema, optionally delimiting
* the name.
*/
public static DBIdentifier newSchema(String name, boolean delimit) {
return newIdentifier(name, DBIdentifierType.SCHEMA, false, delimit);
}
/**
* Constructs a new identifier of type Index.
*/
public static DBIdentifier newIndex(String name) {
return newIdentifier(name, DBIdentifierType.INDEX);
}
/**
* Constructs a new identifier of type Index, optionally delimiting
* the name.
*/
public static DBIdentifier newIndex(String name, boolean delimit) {
return newIdentifier(name, DBIdentifierType.INDEX, false, delimit);
}
/**
* Constructs a new identifier of type Sequence.
*/
public static DBIdentifier newSequence(String name) {
return newIdentifier(name, DBIdentifierType.SEQUENCE);
}
/**
* Constructs a new identifier of type Sequence, optionally delimiting
* the name.
*/
public static DBIdentifier newSequence(String name, boolean delimit) {
return newIdentifier(name, DBIdentifierType.SEQUENCE, false, delimit);
}
/**
* Constructs a new identifier of type ForeignKey.
*/
public static DBIdentifier newForeignKey(String name) {
return newIdentifier(name, DBIdentifierType.FOREIGN_KEY);
}
/**
* Constructs a new identifier of type ForeignKey, optionally delimiting
* the name.
*/
public static DBIdentifier newForeignKey(String name, boolean delimit) {
return newIdentifier(name, DBIdentifierType.FOREIGN_KEY, false, delimit);
}
/**
* Constructs a new identifier of type Constraint.
*/
public static DBIdentifier newConstraint(String name) {
return newIdentifier(name, DBIdentifierType.CONSTRAINT);
}
/**
* Constructs a new identifier of type Constraint, optionally delimiting
* the name.
*/
public static DBIdentifier newConstraint(String name, boolean delimit) {
return newIdentifier(name, DBIdentifierType.CONSTRAINT, false, delimit);
}
/**
* Constructs a new identifier of type Constant.
*/
public static DBIdentifier newConstant(String name) {
return newIdentifier(name, DBIdentifierType.CONSTANT);
}
/**
* Constructs a new identifier of type Column Definition.
*/
public static DBIdentifier newColumnDefinition(String name) {
return newIdentifier(name, DBIdentifierType.COLUMN_DEFINITION);
}
/**
* Constructs a new identifier of type Default.
*/
public static DBIdentifier newDefault(String name) {
return newIdentifier(name, DBIdentifierType.DEFAULT);
}
/**
* Constructs a new identifier with the provided name and type
*/
protected static DBIdentifier newIdentifier(String name, DBIdentifierType id) {
return newIdentifier(name, id, false, false);
}
/**
* Constructs a new identifier with the provided name an type. Optionally,
* converting the name to upper case.
*/
public static DBIdentifier newIdentifier(String name, DBIdentifierType id, boolean toUpper) {
return newIdentifier(name, id, toUpper, false );
}
/**
* Constructs a new identifier (potentially a compound QualifiedDBIdentifier) with the provided
* name an type. Optionally, converting the name to upper case and delimiting it.
*/
protected static DBIdentifier newIdentifier(String name, DBIdentifierType id, boolean toUpper, boolean delimit) {
if (name == null) {
return DBIdentifier.NULL;
}
DBIdentifier dbId = DBIdentifier.NULL;
// Create a DBIDentifier for single component names. Otherwise, create a QualifiedDBIdentifier.
if (!_compoundIdentifier[id.ordinal()] || delimit) {
dbId = new DBIdentifier(name, id, delimit);
if (toUpper) {
return toUpper(dbId);
}
} else {
// Name can be split. Break it up into components and return a path
DBIdentifier[] sNames = DBIdentifier.split(id, name);
dbId = new QualifiedDBIdentifier(sNames);
}
return dbId;
}
/**
* Static equality method for comparing two identifiers.
* @param name1
* @param name2
* @return
*/
public static boolean equal(DBIdentifier name1, DBIdentifier name2) {
boolean name1Null = DBIdentifier.isNull(name1);
if (name1Null && DBIdentifier.isNull(name2)) {
return true;
}
if (name1Null) {
return false;
}
return ((DBIdentifier)name1).equals(name2, false);
}
private void assertNotNull() {
if (this == DBIdentifier.NULL || getType() == DBIdentifierType.NULL) {
throw new IllegalStateException("Cannot modify NULL instance");
}
}
/**
* Returns a new DBIdentifier truncated to length
* @param name
* @param length
* @return
*/
public static DBIdentifier truncate(DBIdentifier name, int length) {
DBIdentifier sName = name.clone();
String strName = sName.getNameInternal();
if (StringUtils.isEmpty(strName)) {
return sName;
}
strName = Normalizer.truncate(strName, length);
sName.setNameInternal(strName);
return sName;
}
/**
* Returns a new DBIdentifier with the given string appended.
* @param name
* @param length
* @return
*/
public static DBIdentifier append(DBIdentifier name, String str) {
DBIdentifier sName = name.clone();
String strName = sName.getNameInternal();
strName = Normalizer.append(strName, str);
sName.setNameInternal(strName);
return sName;
}
/**
* Returns a new DBIdentifier with the given string combined using
* delimiting rules and appropriate separators.
* @param name
* @param length
* @return
*/
public static DBIdentifier combine(DBIdentifier name, String str) {
DBIdentifier sName = name.clone();
String strName = sName.getNameInternal();
strName = Normalizer.combine(strName, str);
sName.setNameInternal(strName);
return sName;
}
/**
* Returns a new DBIdentifier converted to lower case - if not delimited.
* @param name
* @return
*/
public static DBIdentifier toLower(DBIdentifier name) {
return toLower(name, false);
}
/**
* Returns a new DBIdentifier converted to lower case. If delimited,
* force to lower case using force option.
* @param name
* @return
*/
public static DBIdentifier toLower(DBIdentifier name, boolean force) {
if (DBIdentifier.isNull(name)) {
return name;
}
DBIdentifier sName = name.clone();
if (sName.getNameInternal() == null) {
return sName;
}
// Do not convert delimited names to lower case. They may have
// been delimited to preserve case.
if (force || !Normalizer.isDelimited(sName.getNameInternal())) {
sName.setNameInternal(sName.getNameInternal().toLowerCase());
}
return sName;
}
/**
* Returns a new DBIdentifier converted to upper case - if not delimited.
* @param name
* @return
*/
public static DBIdentifier toUpper(DBIdentifier name) {
return toUpper(name, false);
}
/**
* Returns a new DBIdentifier converted to upper case. If delimited,
* force to upper case using force option.
* @param name
* @return
*/
public static DBIdentifier toUpper(DBIdentifier name, boolean force) {
if (DBIdentifier.isNull(name)) {
return name;
}
DBIdentifier sName = name.clone();
if (sName.getNameInternal() == null) {
return sName;
}
// Do not convert delimited names to upper case. They may have
// been delimited to preserve case.
if (force || !Normalizer.isDelimited(sName.getNameInternal())) {
sName.setNameInternal(sName.getNameInternal().toUpperCase());
}
return sName;
}
/**
* Returns a new DBIdentifier with the specified leading string removed.
* @param name
* @return
*/
public static DBIdentifier removeLeading(DBIdentifier name, String leadingStr) {
DBIdentifier sName = name.clone();
if (isEmpty(sName)) {
return sName;
}
String strName = sName.getNameInternal();
int leadingLen = leadingStr.length();
while (strName.startsWith(leadingStr)) {
strName = strName.substring(leadingLen);
}
sName.setNameInternal(strName);
return sName;
}
/**
* Returns a new DBIdentifier with Hungarian notation removed.
* @param name
* @return
*/
public static DBIdentifier removeHungarianNotation(DBIdentifier name) {
DBIdentifier hName = name.clone();
if (isEmpty(hName)) {
return hName;
}
String strName = hName.getNameInternal();
strName = Normalizer.removeHungarianNotation(strName);
hName.setNameInternal(strName);
return hName;
}
/**
* Equality operator which ignores case.
* @param name
* @return
*/
public boolean equalsIgnoreCase(DBIdentifier name) {
return equals(name, true);
}
/**
* Static equality operator which ignores case.
* @param name
* @return
*/
public static boolean equalsIgnoreCase(DBIdentifier name1, DBIdentifier name2) {
boolean name1Null = DBIdentifier.isNull(name1);
if (name1Null && DBIdentifier.isNull(name2)) {
return true;
}
if (name1Null) {
return false;
}
return name1.equals(name2, true);
}
private boolean equals(DBIdentifier sName, boolean ignoreCase) {
if (sName.getNameInternal() == null && getNameInternal() == null) {
return true;
}
if (getNameInternal() == null) {
return false;
}
if (ignoreCase || !Normalizer.isDelimited(getNameInternal())) {
return getNameInternal().equalsIgnoreCase(sName.getNameInternal());
}
return getNameInternal().equals(sName.getNameInternal());
}
/**
* Returns a new identifier with a combined prefix and name using the standard name
* concatenation character ('_').
* @param prefix
*/
public static DBIdentifier preCombine(DBIdentifier name, String prefix) {
if (DBIdentifier.isNull(name)) {
return name;
}
DBIdentifier sName = name.clone();
String strName = sName.getNameInternal();
strName = Normalizer.combine(prefix, strName);
sName.setNameInternal(strName);
return sName;
}
/**
* Returns a new identifier with delimiters removed.
* @param name
* @return
*/
public static DBIdentifier removeDelimiters(DBIdentifier name) {
if (DBIdentifier.isNull(name)) {
return name;
}
DBIdentifier sName = name.clone();
if (isEmpty(sName)) {
return sName;
}
String strName = sName.getNameInternal();
strName = Normalizer.removeDelimiters(strName);
sName.setNameInternal(strName);
return sName;
}
/**
* Returns a new delimiter with leading and trailing spaces removed.
* @param name
* @return
*/
public static DBIdentifier trim(DBIdentifier name) {
if (DBIdentifier.isNull(name)) {
return name;
}
DBIdentifier sName = name.clone();
if (isEmpty(sName)) {
return sName;
}
String strName = sName.getNameInternal();
strName = strName.trim();
sName.setNameInternal(strName);
return sName;
}
/**
* The length of the name, including delimiting characters.
*/
public int length() {
if (DBIdentifier.isNull(this)) {
return 0;
}
return super.length();
}
/**
* Returns true if the identifier is delimited.
*/
public boolean isDelimited() {
if (DBIdentifier.isEmpty(this)) {
return false;
}
return Normalizer.isDelimited(getNameInternal());
}
/**
* Combines an array of names names using standard combining rules and
* returns an identifier of the specified type.
*/
public static DBIdentifier combine(DBIdentifierType id, String...names) {
return newIdentifier(Normalizer.combine(names), id);
}
/**
* Returns the unqualified name of this identifier.
*/
public DBIdentifier getUnqualifiedName() {
return this;
}
}

View File

@ -0,0 +1,56 @@
/*
* 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.jdbc.identifier;
import java.util.Set;
import org.apache.openjpa.jdbc.identifier.DBIdentifier.DBIdentifierType;
import org.apache.openjpa.lib.identifier.IdentifierRule;
/**
* The default DBIdentifier rule. Closely matches SQL92 naming rules.
*/
public class DBIdentifierRule extends IdentifierRule {
public static final String DEFAULT_SQL_92 = "DefaultSQL92";
public static final String SPECIAL_CHARS = " #$&%!?,.:;\"\'";
public DBIdentifierRule() {
setName(DEFAULT_SQL_92);
// SQL92 Identifier rule 1) Can be up to 128 characters long
// setMaxLength(128);
// OpenJPA allows names with a length of 255 by default
setMaxLength(255);
// SQL92 Identifier rule 2) Must begin with a letter
setMustBeginWithLetter(true);
// SQL92 Identifier rule 3) Can contain letters, digits, and underscores
setOnlyLettersDigitsUnderscores(true);
// SQL Identifier rule 4) Can't contain spaces or special characters such
// as #, $, &, %, or punctuation.
setSpecialCharacters(SPECIAL_CHARS);
}
public DBIdentifierRule(DBIdentifierType id, Set<String> reservedWords) {
this();
setName(id.toString());
// SQL Identifier rule 5) Can't be reserved words
setReservedWords(reservedWords);
}
}

View File

@ -0,0 +1,213 @@
/*
* 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.jdbc.identifier;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.NameSet;
import org.apache.openjpa.jdbc.schema.Schema;
import org.apache.openjpa.jdbc.schema.Table;
import org.apache.openjpa.lib.identifier.IdentifierUtil;
import static org.apache.openjpa.jdbc.identifier.DBIdentifier.DBIdentifierType;
/**
* An interface for DB identifier utility-style operations. This interface
* extends the basic operations provided by IdentifierUtil with additional
* operations those specific to DBIdentifiers and identifier conversion.
*/
public interface DBIdentifierUtil extends IdentifierUtil {
// Legacy values for naming operations
public static final int ANY = 0;
public static final int TABLE = 1;
public static final int SEQUENCE = 2;
public static final int COLUMN = 3;
/**
* Shortens the given name to the given maximum length, then checks that
* it is not a reserved word. If it is reserved, appends a "0". If
* the name conflicts with an existing schema component and uniqueness
* checking is enabled, the last character is replace with '0', then
* '1', etc.
* Note that the given max len may be 0 if the database metadata is
* incomplete.
*
* Note: If the name is delimited, make sure the ending delimiter is
* not stripped off.
*/
public DBIdentifier makeIdentifierValid(DBIdentifier sname, NameSet set, int maxLen,
boolean checkForUniqueness);
/**
* Shortens the given name to the given maximum length, then checks that
* it is not a reserved word. If it is reserved, appends a "0". If
* the name conflicts with an existing schema component and uniqueness
* checking is enabled, the last character is replace with '0', then
* '1', etc.
* Note that the given max len may be 0 if the database metadata is
* incomplete.
*
* Note: If the name is delimited, make sure the ending delimiter is
* not stripped off.
*/
public DBIdentifier makeNameValid(String name, NameSet set, int maxLen,
int nameType, boolean checkForUniqueness);
/**
* Returns a valid column name/identifier, based upon the configuration and
* provided parameters.
* @param name
* @param table
* @param maxLen
* @param checkForUniqueness
* @return
*/
public DBIdentifier getValidColumnIdentifier(DBIdentifier name, Table table, int maxLen,
boolean checkForUniqueness);
/**
* Returns a valid index identifier, based upon the configuration and
* provided parameters.
* @param name
* @param table
* @param maxLen
* @param checkForUniqueness
* @return
*/
public DBIdentifier getValidIndexIdentifier(DBIdentifier name, Table table, int maxLen);
/**
* Returns a valid index identifier, based upon the configuration and
* provided parameters.
* @param name
* @param table
* @param maxLen
* @param checkForUniqueness
* @return
*/
public DBIdentifier getValidSequenceIdentifier(DBIdentifier name, Schema schema, int maxLen);
/**
* Returns a valid table identifier, based upon the configuration and provided
* parameters.
* @param name
* @param schema
* @param maxLen
* @return
*/
public DBIdentifier getValidTableIdentifier(DBIdentifier name, Schema schema, int maxLen);
/**
* Returns a valid unique constraint identifier, based upon the configuration and
* provided parameters.
* @param name
* @param table
* @param maxLen
* @return
*/
public DBIdentifier getValidUniqueIdentifier(DBIdentifier name, Table table, int maxLen);
/**
* Returns a valid foreign key identifier, based upon the configuration and
* provided parameters.
* @param name
* @param table
* @param toTable
* @param maxLen
* @return
*/
public DBIdentifier getValidForeignKeyIdentifier(DBIdentifier name, Table table, Table toTable, int maxLen);
/**
* Converts the specified identifier to a format required by the database.
* @param name
* @return
*/
public String toDBName(DBIdentifier name);
/**
* Converts the specified identifier to a format required by the database,
* optionally delimiting the name.
* @param name
* @param delimit
* @return
*/
public String toDBName(DBIdentifier name, boolean delimit);
/**
* Converts the specified string to a format required by the database.
* @param name
* @return
*/
public String toDBName(String name);
/**
* Converts the specified string to a format required by the database,
* optionally delimiting the name.
* @param name
* @return
*/
public String toDBName(String name, boolean delimit);
/**
* Converts the name returned by the database to an identifier of the
* specified type.
* @param name
* @return
*/
public DBIdentifier fromDBName(String name, DBIdentifierType id);
/**
* Appends multiple columns names together into comma delimited string.
* @param columns
* @return
*/
public String appendColumns(Column[] columns);
/**
* Converts the name of the specified delimiter to the appropriate
* case as defined by the configuration.
* @param columns
* @return
*/
public DBIdentifier convertSchemaCase(DBIdentifier schema);
/**
* Appends multiple names together using the appropriate name delimiter.
* @param resultId
* @param names
* @return
*/
public DBIdentifier append(DBIdentifierType resultId, DBIdentifier...names);
/**
* Returns a generated key sequence identifier for the column.
* @param col
* @param maxLen
* @return
*/
public DBIdentifier getGeneratedKeySequenceName(Column col, int maxLen);
/**
* Converts a provided alias to a format specified in the configuration.
* @param alias
* @return
*/
public String convertAlias(String alias);
}

View File

@ -0,0 +1,478 @@
/*
* 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.jdbc.identifier;
import org.apache.commons.lang.StringUtils;
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
import org.apache.openjpa.jdbc.identifier.DBIdentifier.DBIdentifierType;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.NameSet;
import org.apache.openjpa.jdbc.schema.Schema;
import org.apache.openjpa.jdbc.schema.SchemaGroup;
import org.apache.openjpa.jdbc.schema.Table;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.lib.conf.Configurable;
import org.apache.openjpa.lib.conf.Configuration;
import org.apache.openjpa.lib.identifier.IdentifierConfiguration;
import org.apache.openjpa.lib.identifier.IdentifierRule;
import org.apache.openjpa.lib.identifier.IdentifierUtil;
import org.apache.openjpa.lib.identifier.IdentifierUtilImpl;
public class DBIdentifierUtilImpl extends IdentifierUtilImpl implements DBIdentifierUtil,
Configurable {
private JDBCConfiguration _conf = null;
public DBIdentifierUtilImpl() {
}
public DBIdentifierUtilImpl(IdentifierConfiguration config) {
super(config);
}
public DBIdentifier getValidColumnIdentifier(DBIdentifier name, Table table,
int maxLen, boolean checkForUniqueness) {
if (DBIdentifier.isNull(name)) {
return name;
}
String rule = name.getType().name();
maxLen = getMaxLen(rule, name, maxLen);
DBIdentifier sName = DBIdentifier.removeLeading(name, IdentifierUtil.UNDERSCORE);
return makeIdentifierValid(sName, table, maxLen, checkForUniqueness);
}
public DBIdentifier getValidForeignKeyIdentifier(DBIdentifier name, Table table, Table toTable, int maxLen) {
if (DBIdentifier.isNull(name)) {
return name;
}
String rule = name.getType().name();
maxLen = getMaxLen(rule, name, maxLen);
DBIdentifier sName = makeName(rule, name, table, "F");
return makeIdentifierValid(sName, table.getSchema().getSchemaGroup(),
maxLen, true);
}
public DBIdentifier getValidUniqueIdentifier(DBIdentifier name, Table table, int maxLen) {
if (DBIdentifier.isNull(name)) {
return name;
}
String rule = name.getType().name();
maxLen = getMaxLen(rule, name, maxLen);
DBIdentifier sName = makeName(rule, name, table, "U");
return makeIdentifierValid(sName, table.getSchema().getSchemaGroup(),
maxLen, true);
}
public DBIdentifier getValidIndexIdentifier(DBIdentifier name, Table table, int maxLen) {
if (DBIdentifier.isNull(name)) {
return name;
}
String rule = name.getType().name();
maxLen = getMaxLen(rule, name, maxLen);
DBIdentifier sName = makeName(rule, name, table, "I");
return makeIdentifierValid(sName, table.getSchema().getSchemaGroup(),
maxLen, true);
}
public DBIdentifier getValidSequenceIdentifier(DBIdentifier name, Schema schema, int maxLen) {
if (DBIdentifier.isNull(name)) {
return name;
}
String rule = name.getType().name();
maxLen = getMaxLen(rule, name, maxLen);
DBIdentifier sName = makeName(rule, name, "S");
return makeIdentifierValid(sName, schema.getSchemaGroup(), maxLen, true);
}
public DBIdentifier getValidTableIdentifier(DBIdentifier name, Schema schema, int maxLen) {
if (DBIdentifier.isNull(name)) {
return name;
}
String rule = name.getType().name();
maxLen = getMaxLen(rule, name, maxLen);
DBIdentifier sName = makeName(rule, name, null);
return makeIdentifierValid(sName, schema.getSchemaGroup(),
maxLen, true);
}
public DBIdentifier makeNameValid(String name, NameSet set, int maxLen,
int nameType, boolean checkForUniqueness) {
DBIdentifierType id = DBIdentifierType.DEFAULT;
switch (nameType) {
case DBIdentifierUtil.TABLE:
id = DBIdentifierType.TABLE;
break;
case DBIdentifierUtil.SEQUENCE:
id = DBIdentifierType.SEQUENCE;
break;
case DBIdentifierUtil.COLUMN:
id = DBIdentifierType.COLUMN;
break;
}
return makeIdentifierValid(DBIdentifier.newIdentifier(name, id), set, maxLen, checkForUniqueness);
}
public DBIdentifier makeIdentifierValid(DBIdentifier sname, NameSet set, int maxLen,
boolean checkForUniqueness) {
DBIdentifier validName = sname;
String rule = sname.getType().name();
maxLen = getMaxLen(rule, validName, maxLen);
int nameLen = validName.getName().length();
if (nameLen > maxLen) {
validName = DBIdentifier.truncate(validName, nameLen - maxLen);
nameLen = validName.getName().length();
}
if (isReservedWord(rule, validName.getName())) {
if (nameLen == maxLen)
validName = DBIdentifier.truncate(validName, 1);
validName = DBIdentifier.append(validName, "0");
nameLen = validName.getName().length();
}
// now make sure the name is unique
if (set != null && checkForUniqueness) {
for (int version = 1, chars = 1; true; version++) {
// for table names, we check for the table itself in case the
// name set is lazy about schema reflection
if (validName.getType() == DBIdentifierType.TABLE) {
if (!((SchemaGroup) set).isKnownTable(QualifiedDBIdentifier.getPath(validName)))
break;
} else if (validName.getType() == DBIdentifierType.SEQUENCE) {
if (!((SchemaGroup) set).isKnownSequence(QualifiedDBIdentifier.getPath(validName)))
break;
} else {
if (!set.isNameTaken(validName))
break;
}
// a single char for the version is probably enough, but might
// as well be general about it...
if (version > 1) {
validName = DBIdentifier.truncate(validName, chars);
}
if (version >= Math.pow(10, chars))
chars++;
if (nameLen + chars > maxLen) {
validName = DBIdentifier.truncate(validName, nameLen + chars - maxLen);
}
validName = DBIdentifier.append(validName, Integer.toString(version));
nameLen = validName.getName().length();
}
}
if (validName.isDelimited()) {
String delimCase = getIdentifierConfiguration().getDelimitedCase();
if (delimCase.equals(CASE_LOWER)) {
return DBIdentifier.toLower(validName,true);
}
else if (delimCase.equals(CASE_UPPER)) {
return DBIdentifier.toUpper(validName,true);
}
else {
return validName;
}
}
return DBIdentifier.toUpper(validName);
}
/**
* Converts the name to a name which can be used within a SQL statement. Uses
* the appropriate delimiters and separators.
* @parm name a DBIdentifier
*/
public String toDBName(DBIdentifier name) {
return toDBName(name, true);
}
/**
* Converts the name to a name which can be used within a SQL statement. Uses
* the appropriate delimiters and separators.
* @parm name a DBIdentifier
* @param delimit If true, allows the name to be delimited, if necessary.
* Otherwise, the identifier is not delimited.
*/
public String toDBName(DBIdentifier name, boolean delimit) {
if (DBIdentifier.isNull(name)) {
return null;
}
if (getIdentifierConfiguration().getSupportsDelimitedIdentifiers() && delimit
&& getIdentifierConfiguration().delimitAll() && !name.isDelimited()) {
return delimit(name, true);
}
String rule = name.getType().name();
if (name instanceof QualifiedDBIdentifier) {
QualifiedDBIdentifier path = (QualifiedDBIdentifier)name;
return convertFull(Normalizer.getNamingConfiguration(), rule, path.getName());
}
return convert(Normalizer.getNamingConfiguration(), rule, name.getName());
}
/**
* Converts the identifier to a format appropriate for the configuration.
* Delimits if necessary
*/
public String toDBName(String name) {
return toDBName(name, true);
}
/**
* Converts the identifier to a format appropriate for the configuration using
* the default naming rule.
* @param delimit If false, do not delimit. Otherwise, delimit if necessary.
*/
public String toDBName(String name, boolean delimit) {
return toDBName(getIdentifierConfiguration().getDefaultIdentifierRule().getName(), name, delimit);
}
/**
* Converts the identifier to a format appropriate for the configuration using
* the specified naming rule.
* @param delimit If false, do not delimit. Otherwise, delimit if necessary.
*/
private String toDBName(String rule, String name, boolean delimit) {
if (name == null) {
return null;
}
if (getIdentifierConfiguration().getSupportsDelimitedIdentifiers() && delimit &&
getIdentifierConfiguration().delimitAll() && !Normalizer.isDelimited(name)) {
return delimit(rule, name, true);
}
return convert(Normalizer.getNamingConfiguration(), rule, name);
}
/**
* Creates a new identifier of a given type based upon the name returned
* from the database.
*/
public DBIdentifier fromDBName(String name, DBIdentifierType id) {
if (name == null) {
return DBIdentifier.NULL;
}
if (!getIdentifierConfiguration().getSupportsDelimitedIdentifiers()) {
return DBIdentifier.newIdentifier(name, id);
}
String delimCase = getIdentifierConfiguration().getDelimitedCase();
String nonDelimCase = getIdentifierConfiguration().getSchemaCase();
String caseName = name;
// If delimited and non-delimited case are the same, don't change
// case or try to determine whether delimiting is required. Let the
// normalizer figure it out using standard rules.
if (delimCase.equals(nonDelimCase)) {
return DBIdentifier.newIdentifier(name, id, false, false);
}
// Otherwise, try to determine whether to delimit based on an expected vs.
// actual name comparison.
if (delimCase.equals(CASE_PRESERVE)) {
if (nonDelimCase.equals(CASE_LOWER)) {
caseName = name.toLowerCase();
} else {
caseName = name.toUpperCase();
}
} else if (delimCase.equals(CASE_LOWER)) {
if (nonDelimCase.equals(CASE_UPPER)) {
caseName = name.toUpperCase();
}
} else if (delimCase.equals(CASE_UPPER)) {
if (nonDelimCase.equals(CASE_LOWER)) {
caseName = name.toLowerCase();
}
}
boolean delimit = !caseName.equals(name) || getIdentifierConfiguration().delimitAll();
return DBIdentifier.newIdentifier((delimit ? name : caseName), id, false, delimit);
}
public DBIdentifier append(DBIdentifierType resultId, DBIdentifier...names) {
if (names == null || names.length == 0) {
return DBIdentifier.NULL;
}
DBIdentifier sName = DBIdentifier.newIdentifier("", resultId);
for (DBIdentifier name : names) {
DBIdentifier.append(sName, name.getName());
}
return sName;
}
public String appendColumns(Column[] columns) {
if (columns == null || columns.length == 0) {
return "";
}
if (columns.length == 1) {
return toDBName(columns[0].getIdentifier());
}
StringBuilder colsb = new StringBuilder("");
for (int i = 0; i < columns.length; i++) {
colsb.append(toDBName(columns[i].getIdentifier()));
if (i < (columns.length - 1)) {
colsb.append(", ");
}
}
return colsb.toString();
}
public String delimit(DBIdentifier name, boolean force) {
String rule = name.getType().name();
// If this is a compound path, each item must be delimited
// separately
if (name instanceof QualifiedDBIdentifier) {
QualifiedDBIdentifier path = (QualifiedDBIdentifier)name;
// Make sure this is a qualified path before delimiting
// separately
if (!((path.getType() == DBIdentifierType.COLUMN &&
path.isUnqualifiedColumn()) ||
(path.getType() != DBIdentifierType.COLUMN &&
path.isUnqualifiedObject()))) {
DBIdentifier[] names = QualifiedDBIdentifier.splitPath(name);
for (int i = 0; i < names.length; i++) {
DBIdentifier sName = names[i].getUnqualifiedName();
if (!sName.isDelimited()) {
String pRule = sName.getType().name();
names[i].setName(delimit(pRule, sName.getName(), force));
}
}
return QualifiedDBIdentifier.newPath(names).getName();
}
}
return delimit(rule, name.getName(), force);
}
public String shorten(String name, int targetLength) {
return DBDictionary.shorten(name, targetLength);
}
public DBIdentifier getGeneratedKeySequenceName(Column col, int maxLen) {
DBIdentifier tname = col.getTableIdentifier();
DBIdentifier cname = col.getIdentifier();
int max = maxLen;
int extraChars = -max + tname.getName().length() + 1 // <tname> + '_'
+ cname.getName().length() + 4; // <cname> + '_SEQ'
String tsname = tname.getName();
if (extraChars > 0) {
// this assumes that tname is longer than extraChars
tsname = tsname.substring(0, tsname.length() - extraChars);
}
return DBIdentifier.combine(DBIdentifierType.SEQUENCE, tsname, cname.getName(), "SEQ");
}
/**
* Convert the specified schema name to a name that the database will
* be able to understand in metadata operations.
*/
public DBIdentifier convertSchemaCase(DBIdentifier name) {
if (DBIdentifier.isNull(name))
return DBIdentifier.NULL;
DBIdentifier sName = name.clone();
// Handle delimited string differently. Return unquoted name.
String delimCase = getIdentifierConfiguration().getDelimitedCase();
if (/* getNamingConfiguration().delimitAll() || */ name.isDelimited()) {
if (CASE_UPPER.equals(delimCase)) {
sName = DBIdentifier.toUpper(sName,true);
}
else if (CASE_LOWER.equals(delimCase)) {
sName = DBIdentifier.toLower(sName,true);
}
return DBIdentifier.removeDelimiters(sName);
}
if (!getIdentifierConfiguration().delimitAll()) {
// Not delimited, use the base schema case expected by the DB
String schemaCase = getIdentifierConfiguration().getSchemaCase();
if (CASE_LOWER.equals(schemaCase))
return DBIdentifier.toLower(sName);
if (CASE_PRESERVE.equals(schemaCase))
return sName;
return DBIdentifier.toUpper(sName);
}
return sName;
}
/**
* Converts a column alias to use the appropriate delimiters
*/
public String convertAlias(String alias) {
String[] names = Normalizer.splitName(alias);
if (names.length <= 1) {
// Nothing to split
return alias;
}
// Skip the the first name. It is the alias (T0, T1, etc.)
for (int i = 1; i < names.length; i++) {
names[i] = toDBName(getIdentifierConfiguration().getDefaultIdentifierRule().toString(), names[i], true);
}
return joinNames(getIdentifierConfiguration().getDefaultIdentifierRule(), names);
}
private DBIdentifier makeName(String rule, DBIdentifier name, Table tbl, String prefix) {
DBIdentifier sName = DBIdentifier.removeLeading(name, IdentifierUtil.UNDERSCORE);
String tableName = tbl.getIdentifier().getName();
int len = Math.min(tableName.length(), 7);
String str = combineNames(rule, new String[] { prefix == null ? "" : prefix,
shorten(tableName, len), sName.getName() });
sName.setName(str);
return sName;
}
private DBIdentifier makeName(String rule, DBIdentifier name, String prefix) {
DBIdentifier sName = DBIdentifier.removeLeading(name, IdentifierUtil.UNDERSCORE);
if (!StringUtils.isEmpty(prefix)) {
sName = DBIdentifier.preCombine(sName, prefix);
}
return sName;
}
private int getMaxLen(String rule, DBIdentifier name, int maxLen) {
IdentifierConfiguration config = getIdentifierConfiguration();
if (maxLen < 1) {
IdentifierRule nrule = config.getIdentifierRule(rule);
maxLen = nrule.getMaxLength();
}
// Subtract delimiter length if name is delimited or will be delimited
if (config.delimitAll() || name.isDelimited()) {
maxLen = maxLen - (config.getLeadingDelimiter().length() + config.getTrailingDelimiter().length());
}
return maxLen;
}
/**
* System configuration.
*/
public JDBCConfiguration getConfiguration() {
return _conf;
}
@Override
public void setConfiguration(Configuration conf) {
_conf = (JDBCConfiguration)conf;
}
}

View File

@ -0,0 +1,81 @@
/*
* 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.jdbc.identifier;
import java.util.HashMap;
import java.util.Map;
import org.apache.openjpa.lib.identifier.IdentifierConfiguration;
import org.apache.openjpa.lib.identifier.IdentifierRule;
import org.apache.openjpa.lib.identifier.IdentifierUtil;
public class DefaultIdentifierConfiguration implements IdentifierConfiguration {
private DBIdentifierRule normalizingRule = new DBIdentifierRule();
private Map<String, IdentifierRule> normalizingRules = new HashMap<String, IdentifierRule>();
public DefaultIdentifierConfiguration() {
normalizingRules.put(IdentifierRule.DEFAULT_RULE, normalizingRule);
}
public boolean delimitAll() {
return false;
}
public IdentifierRule getDefaultIdentifierRule() {
return normalizingRule;
}
public String getDelimitedCase() {
return IdentifierUtil.CASE_PRESERVE;
}
public String getSchemaCase() {
return IdentifierUtil.CASE_PRESERVE;
}
public String getLeadingDelimiter() {
return IdentifierUtil.DOUBLE_QUOTE;
}
public String getIdentifierDelimiter() {
return IdentifierUtil.DOT;
}
public String getIdentifierConcatenator() {
return IdentifierUtil.UNDERSCORE;
}
public <T> IdentifierRule getIdentifierRule(T t) {
return normalizingRule;
}
@SuppressWarnings("unchecked")
public Map<String, IdentifierRule> getIdentifierRules() {
return normalizingRules;
}
public String getTrailingDelimiter() {
return IdentifierUtil.DOUBLE_QUOTE;
}
public boolean getSupportsDelimitedIdentifiers() {
return true;
}
}

View File

@ -0,0 +1,311 @@
/*
* 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.jdbc.identifier;
import org.apache.commons.lang.StringUtils;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.lib.identifier.IdentifierConfiguration;
import org.apache.openjpa.lib.identifier.IdentifierRule;
import org.apache.openjpa.lib.identifier.IdentifierUtil;
/**
* Static utility class used for operating on string based identifiers.
*/
public class Normalizer {
private static IdentifierUtil normalizer =
new DBIdentifierUtilImpl(new DefaultIdentifierConfiguration());
private static IdentifierRule defaultRule;
static {
defaultRule = normalizer.getIdentifierConfiguration().getDefaultIdentifierRule();
}
public static IdentifierConfiguration getNamingConfiguration() {
return normalizer.getIdentifierConfiguration();
}
/**
* Normalizes a multi-part name
* @param name
* @return
*/
public static String normalizeMulti(String name) {
if (StringUtils.isEmpty(name)) {
return name;
}
String[] names = normalizer.splitName(defaultRule, name);
return normalizer.joinNames(defaultRule, names);
}
/**
* Normalizes a single part name
* @param name
* @return
*/
public static String normalizeString(String name) {
if (StringUtils.isEmpty(name)) {
return name;
}
if (!normalizer.isDelimited(defaultRule, name)) {
// If not delimited, delimit the string if necessary
return normalizer.delimit(defaultRule, name);
}
return name;
}
/**
* Returns true if the name is delimited with default delimiters
* @param name
* @return
*/
public static boolean isDelimited(String name) {
if (StringUtils.isEmpty(name)) {
return false;
}
return normalizer.isDelimited(defaultRule, name);
}
/**
* Splits names into individual components and compares individually
* for equality
* @param name1
* @param name2
* @return
*/
public static boolean fullNamesEqual(String name1, String name2) {
if (StringUtils.isEmpty(name1) && StringUtils.isEmpty(name2)) {
return true;
}
// Split multi-part names into individual components and compare
// each component. If delimited, do case compare.
String[] names1 = normalizer.splitName(defaultRule, name1);
String[] names2 = normalizer.splitName(defaultRule, name2);
if (names1.length != names2.length) {
return false;
}
for (int i = 0; i < names1.length; i++) {
if (normalizer.isDelimited(defaultRule, names1[i])) {
if (!StringUtils.equals(names1[i],names2[i])) {
return false;
}
} else {
if (!StringUtils.equalsIgnoreCase(names1[i],names2[i])) {
return false;
}
}
}
return true;
}
/**
* Compares two string names for equality. If delimited, does a
* case comparison. If not delimited, does a case insensitive
* comparison.
* @param name1
* @param name2
* @return
*/
public static boolean namesEqual(String name1, String name2) {
if (StringUtils.isEmpty(name1) && StringUtils.isEmpty(name2)) {
return true;
}
if (normalizer.isDelimited(defaultRule, name1)) {
if (!StringUtils.equals(name1, name2)) {
return false;
}
} else {
if (!StringUtils.equalsIgnoreCase(name1, name2)) {
return false;
}
}
return true;
}
/**
* Normalizes a name, if not delimited, converts to uppercase.
* @param name
* @return
*/
public static String normalizeUpper(String name) {
String nName = normalizeString(name);
// Do not convert delimited names to upper case. They may have
// been delimited to preserve case.
if (!isDelimited(nName)) {
nName = name.toUpperCase();
}
return nName;
}
/**
* Splits a name into normalized components
* @param name
* @return
*/
public static String[] splitName(String name) {
return normalizer.splitName(defaultRule, name);
}
/**
* Splits a name into normalized components using the specified
* name delimiter (ex. schema:table, delim = : --> { schema, table }
* @param name
* @return
*/
public static String[] splitName(String name, String delim) {
return normalizer.splitName(defaultRule, name, delim);
}
/**
* Joins multiple names using default identifier rules.
* @param names
* @return
*/
public static String joinNames(String[] names) {
return normalizer.joinNames(defaultRule, names);
}
/**
* Joins multiple names using the specified delimiter.
* @param names
* @return
*/
public static String joinNames(String[] names, String delimiter) {
return normalizer.joinNames(defaultRule, names, delimiter);
}
/**
* Joins two names using the default identifier rules.
* @param names
* @return
*/
public static String joinNames(String name1, String name2) {
return joinNames(new String[] { name1, name2});
}
/**
* Truncates a name to the specified length while maintaining
* delimiters.
* @param name
* @param length
* @return
*/
public static String truncate(String name, int length) {
return normalizer.truncateName(defaultRule, name, length);
}
/**
* Convert a normalized name to a name using the specified configuration and
* naming rule.
* Note: Currently only delimiters are converted.
* @param config
* @param rule
* @param name
* @return
*/
public static String convert(IdentifierConfiguration config, String rule, String name) {
return normalizer.convert(config, rule, name);
}
/**
* Combines two names using default identifier rules.
* @param name1
* @param name2
* @return
*/
public static String combine(String name1, String name2) {
return normalizer.combineNames(defaultRule, name1, name2);
}
/**
* Combines multiple names using default identifier rules.
* @param name1
* @param name2
* @return
*/
public static String combine(String...names) {
return normalizer.combineNames(defaultRule, names);
}
/**
* Appends one string to another using default identifier rules.
* @param name1
* @param name2
* @return
*/
public static String append(String name1, String name2) {
return normalizer.appendNames(defaultRule, name1, name2);
}
/**
* Removes Hungarian notation from a string.
* @param name1
* @param name2
* @return
*/
public static String removeHungarianNotation(String name) {
return normalizer.removeHungarianNotation(defaultRule, name);
}
/**
* Removes default delimiters from a string.
* @param name1
* @param name2
* @return
*/
public static String removeDelimiters(String name) {
return normalizer.removeDelimiters(defaultRule, name);
}
/**
* Delimits a string if necessary, optionally forcing it to be
* delimited.
* @param name1
* @param name2
* @return
*/
public static String delimit(String name, boolean force) {
return normalizer.delimit(defaultRule, name, force);
}
/**
* Determines whether a name can be split into multiple components.
* @param name1
* @param name2
* @return
*/
public static boolean canSplit(String name) {
return normalizer.canSplit(defaultRule, name);
}
/**
* Determines whether a name can be split into multiple components, taking
* into account the specified delimiter.
* @param name1
* @param name2
* @return
*/
public static boolean canSplit(String name, String delim) {
return normalizer.canSplit(defaultRule, name, delim);
}
}

View File

@ -0,0 +1,359 @@
/*
* 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.jdbc.identifier;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import org.apache.openjpa.lib.identifier.Identifier;
/**
* This class extends DBIdentifier to provide support for qualified identifiers
* such as schema qualified tables and table qualified columns. It provides methods
* to create qualified identifiers from individual identifiers.
*
*/
public class QualifiedDBIdentifier extends DBIdentifier implements Identifier, Cloneable, Serializable {
private DBIdentifier _schemaName = DBIdentifier.NULL; // The schema name
// The table name if the object (column, constraint) is qualified by a table name
private DBIdentifier _objectTableName = DBIdentifier.NULL;
protected QualifiedDBIdentifier(DBIdentifier... sNames) {
setPath(sNames);
}
/**
* Creates a qualified identifier based upon an array of DBIdentifiers. Identifiers
* must be specified in order.
* @param names
* @return
*/
public static QualifiedDBIdentifier newPath(DBIdentifier...names) {
return new QualifiedDBIdentifier(names);
}
/**
* Set the identifiers that make up the path. Identifiers must be specified
* in path order. (ex. [ table, column ] )
* @param sNames
*/
public void setPath(DBIdentifier...sNames) {
resetNames();
if (sNames == null || sNames.length == 0) {
return;
}
if (sNames.length == 1) {
DBIdentifier sName = sNames[0];
if (sName.getType() == DBIdentifierType.SCHEMA) {
setSchemaName(sName.clone());
}
setName(sName.clone());
setType(sName.getType());
return;
}
for (int i = (sNames.length - 1); i >= 0; i--) {
DBIdentifier sName = sNames[i];
if (DBIdentifier.isNull(sName)) {
continue;
}
if (i == (sNames.length - 1) && sNames.length != 1) {
setName(sName.clone());
} else {
if (sName.getType() == DBIdentifierType.SCHEMA) {
setSchemaName(sName.clone());
}
else if (sName.getType() == DBIdentifierType.TABLE) {
setObjectTableName(sName.clone());
}
}
}
}
// Reset the path names
private void resetNames() {
_schemaName = DBIdentifier.NULL;
_objectTableName = DBIdentifier.NULL;
}
/**
* Splits a qualified path into separate identifiers.
* @param sName
* @return
*/
public static DBIdentifier[] splitPath(DBIdentifier sName) {
if (sName instanceof QualifiedDBIdentifier && sName.getType() != DBIdentifierType.SCHEMA) {
QualifiedDBIdentifier path = (QualifiedDBIdentifier)sName;
List<DBIdentifier> names = new ArrayList<DBIdentifier>();
if (!DBIdentifier.isNull(path.getSchemaName())) {
names.add(path.getSchemaName().clone());
}
if (!DBIdentifier.isNull(path.getObjectTableName())) {
names.add(path.getObjectTableName().clone());
}
if (!DBIdentifier.isNull(path.getIdentifier())) {
names.add(((DBIdentifier)path).clone());
}
return names.toArray(new DBIdentifier[names.size()]);
}
if (sName instanceof DBIdentifier) {
return new DBIdentifier[] { sName.clone() };
}
return new DBIdentifier[] {};
}
/**
* Creates a qualified path from an identifier.
* @param sName
* @return
*/
public static QualifiedDBIdentifier getPath(DBIdentifier sName) {
if (sName instanceof QualifiedDBIdentifier) {
return (QualifiedDBIdentifier)sName.clone();
}
return QualifiedDBIdentifier.newPath(sName);
}
/**
*Sets the schema component of the path.
*/
public void setSchemaName(DBIdentifier schemaName) {
_schemaName = schemaName;
}
/**
* Gets the schema component of the path.
* @return
*/
public DBIdentifier getSchemaName() {
return _schemaName;
}
/**
* Sets the object table name component of the path, if the path
* is a table qualified identifier such as a constraint or column.
*/
public void setObjectTableName(DBIdentifier objectName) {
_objectTableName = objectName;
}
/**
* Gets the object table name component of the path, if the path
* is a table qualified identifier such as a constraint or column.
*/
public DBIdentifier getObjectTableName() {
return _objectTableName;
}
/**
* Returns true if this object is not qualified by a schema component.
* @return
*/
public boolean isUnqualifiedObject() {
return DBIdentifier.isNull(getSchemaName());
}
/**
* Returns true if this object is not qualified by a table or schema
* component.
* @return
*/
public boolean isUnqualifiedColumn() {
return DBIdentifier.isNull(getObjectTableName()) && DBIdentifier.isNull(getSchemaName());
}
/**
* Equality operator.
*/
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (obj instanceof QualifiedDBIdentifier) {
QualifiedDBIdentifier sPath = (QualifiedDBIdentifier)obj;
return DBIdentifier.equal(sPath.getSchemaName(), getSchemaName()) &&
DBIdentifier.equal(sPath.getObjectTableName(), getObjectTableName()) &&
DBIdentifier.equal(sPath, this);
}
else if (obj instanceof DBIdentifier) {
DBIdentifier sName = (DBIdentifier)obj;
return DBIdentifier.equal(sName, this);
} else if (obj instanceof String) {
return obj.equals(this.getName());
}
throw new IllegalArgumentException("Cannot compare to type: " + obj.getClass().getName());
}
/**
* Compares two qualified identifiers for equality.
* @param path1
* @param path2
* @return
*/
public static boolean pathEqual(QualifiedDBIdentifier path1, QualifiedDBIdentifier path2) {
if (path1 == null && path2 == null) {
return true;
}
if (path1 == null) {
return false;
}
DBIdentifier[] names1 = QualifiedDBIdentifier.splitPath(path1);
DBIdentifier[] names2 = QualifiedDBIdentifier.splitPath(path2);
if (names1.length != names2.length) {
return false;
}
for (int i = 0; i < names1.length; i++) {
if (!DBIdentifier.equal(names1[i], names2[i])) {
return false;
}
}
return true;
}
/**
* Returns a fully qualified name as a string.
*/
public String toString() {
return getName();
}
/**
* Returns the fully qualified name as a string
*/
public String getName() {
// If no schema or object or table qualifier, return the base name
if (DBIdentifier.isEmpty(_schemaName) && DBIdentifier.isEmpty(_objectTableName)) {
return getBaseName();
}
DBIdentifier[] names = QualifiedDBIdentifier.splitPath(this);
return DBIdentifier.join(names);
}
/**
* Returns the base name of this qualified name. For example, if the
* qualified name is a schema qualified table, the table name is returned.
* @return
*/
public String getBaseName() {
return super.getName();
}
/**
* Returns this object as a DBIdentifier.
* @return
*/
public DBIdentifier getIdentifier() {
return this;
}
/**
* Set the name of this qualified identifier. Splits the string into
* multiple components. This method assumes the type does not change.
*/
public void setName(String name) {
// Split apart name into components
DBIdentifier[] sNames = DBIdentifier.split(getType(), name);
setPath(sNames);
}
/**
* Set the base name component of this compound identifier
* @param name
*/
protected void setBaseName(String name) {
super.setName(name);
}
/**
* Returns the length of the qualified identifier, including delimiters
* and name separators.
*/
public int length() {
String name = getName();
if (name == null) {
return 0;
}
return name.length();
}
/**
* Compares this identifier with another identifier.
*/
public int compareTo(Identifier o) {
if (o instanceof DBIdentifier) {
if (o == null || o == DBIdentifier.NULL)
return -1;
return super.compareTo(o);
}
return getName().compareTo(o.getName());
}
/**
* Returns true if all identifiers within this compound identifier are
* delimited. Otherwise, false.
*/
@Override
public boolean isDelimited() {
if (DBIdentifier.isEmpty(this)) {
return false;
}
if (!DBIdentifier.isNull(getObjectTableName())) {
if (!Normalizer.isDelimited(getObjectTableName().getName())) {
return false;
}
}
if (!DBIdentifier.isNull(getSchemaName())) {
if (!Normalizer.isDelimited(getSchemaName().getName())) {
return false;
}
}
return super.isDelimited();
}
/**
* Returns a new unqualified name based on this instance.
*/
@Override
public DBIdentifier getUnqualifiedName() {
QualifiedDBIdentifier newName = (QualifiedDBIdentifier)clone();
newName.setObjectTableName(DBIdentifier.NULL);
newName.setSchemaName(DBIdentifier.NULL);
return newName;
}
/**
* Creates a clone of this identifier.
*/
public QualifiedDBIdentifier clone() {
QualifiedDBIdentifier sPath = new QualifiedDBIdentifier();
sPath.setObjectTableName(getObjectTableName().clone());
sPath.setSchemaName(getSchemaName().clone());
sPath.setBaseName(super.getName());
sPath.setType(getType());
return sPath;
}
}

View File

@ -50,7 +50,7 @@ public class ClassTableJDBCSeq
private static final Localizer _loc = Localizer.forPackage
(ClassTableJDBCSeq.class);
private final Map _stats = new HashMap();
private final Map<String, Status> _stats = new HashMap<String, Status>();
private boolean _ignore = false;
private boolean _aliases = false;
@ -113,7 +113,7 @@ public class ClassTableJDBCSeq
protected Column addPrimaryKeyColumn(Table table) {
DBDictionary dict = getConfiguration().getDBDictionaryInstance();
Column pkColumn = table.addColumn(dict.getValidColumnName(
getPrimaryKeyColumn(), table));
getPrimaryKeyColumnIdentifier(), table));
pkColumn.setType(dict.getPreferredType(Types.VARCHAR));
pkColumn.setJavaType(JavaTypes.STRING);
pkColumn.setSize(dict.characterColumnSize);
@ -223,7 +223,7 @@ public class ClassTableJDBCSeq
ClassArgParser cap = conf.getMetaDataRepositoryInstance()
.getMetaDataFactory().newClassArgParser();
cap.setClassLoader(loader);
Class cls = cap.parseTypes(args[0])[0];
Class<?> cls = cap.parseTypes(args[0])[0];
if (repos == null)
repos = conf.getMappingRepositoryInstance();

View File

@ -23,6 +23,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.meta.ClassMapping;
import org.apache.openjpa.jdbc.meta.FieldMapping;
import org.apache.openjpa.jdbc.sql.DBDictionary;
@ -87,15 +88,15 @@ public class MixedLockManager extends PessimisticLockManager {
//
if(!dict.supportsLockingWithMultipleTables) {
// look for columns mapped to secondary tables which need to be locked
Map<String,FieldMapping> colsMappedToSecTable = new HashMap<String,FieldMapping>();
Map<DBIdentifier,FieldMapping> colsMappedToSecTable = new HashMap<DBIdentifier,FieldMapping>();
FieldMapping fms[] = mapping.getFieldMappings();
for( FieldMapping fm : fms) {
String secTableName = fm.getMappingInfo().getTableName();
if( secTableName != null ) {
DBIdentifier secTableName = fm.getMappingInfo().getTableIdentifier();
if(!DBIdentifier.isNull(secTableName)) {
colsMappedToSecTable.put(secTableName, fm);
}
}
for( String secTableName : colsMappedToSecTable.keySet()) {
for( DBIdentifier secTableName : colsMappedToSecTable.keySet()) {
FieldMapping fm = colsMappedToSecTable.get(secTableName);
// select only the PK columns, since we just want to lock
Select select = factory.newSelect();

View File

@ -27,6 +27,8 @@ import java.text.MessageFormat;
import org.apache.openjpa.conf.OpenJPAConfiguration;
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
import org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.identifier.QualifiedDBIdentifier;
import org.apache.openjpa.jdbc.meta.ClassMapping;
import org.apache.openjpa.jdbc.schema.Schema;
import org.apache.openjpa.jdbc.schema.SchemaGroup;
@ -69,7 +71,7 @@ public class NativeJDBCSeq
private static Localizer _loc = Localizer.forPackage(NativeJDBCSeq.class);
private JDBCConfiguration _conf = null;
private String _seqName = "OPENJPA_SEQUENCE";
private DBIdentifier _seqName = DBIdentifier.newSequence("OPENJPA_SEQUENCE");
private int _increment = 1;
private int _initial = 1;
private int _allocate = 0;
@ -78,23 +80,24 @@ public class NativeJDBCSeq
// for deprecated auto-configuration support
private String _format = null;
private String _tableName = "DUAL";
private DBIdentifier _tableName = DBIdentifier.newTable("DUAL");
private boolean _subTable = false;
private String _schema = null;
private DBIdentifier _schema = DBIdentifier.NULL;
/**
* The sequence name. Defaults to <code>OPENJPA_SEQUENCE</code>.
*/
// @GETTER
public String getSequence() {
return _seqName;
return _seqName.getName();
}
/**
* The sequence name. Defaults to <code>OPENJPA_SEQUENCE</code>.
*/
public void setSequence(String seqName) {
_seqName = seqName;
_seqName = DBIdentifier.newSequence(seqName);
}
/**
@ -153,7 +156,7 @@ public class NativeJDBCSeq
*/
@Deprecated
public void setTableName(String table) {
_tableName = table;
_tableName = DBIdentifier.newTable(table);
}
/**
@ -168,14 +171,15 @@ public class NativeJDBCSeq
@Override
public void addSchema(ClassMapping mapping, SchemaGroup group) {
// sequence already exists?
if (group.isKnownSequence(_seqName))
QualifiedDBIdentifier path = QualifiedDBIdentifier.getPath(_seqName);
if (group.isKnownSequence(path))
return;
String schemaName = getSchema();
if (schemaName == null || schemaName.length() == 0) {
schemaName = Strings.getPackageName(_seqName);
if (schemaName.length() == 0)
schemaName = Schemas.getNewTableSchema(_conf);
DBIdentifier schemaName = getSchemaIdentifier();
if (DBIdentifier.isEmpty(schemaName)) {
schemaName = path.getSchemaName();
if (DBIdentifier.isEmpty(schemaName))
schemaName = Schemas.getNewTableSchemaIdentifier(_conf);
}
// create table in this group
@ -183,8 +187,6 @@ public class NativeJDBCSeq
if (schema == null)
schema = group.addSchema(schemaName);
schema.importSequence(_seq);
// TODO: temp until a more global name solution is implemented
schema.addDelimSequenceName(_conf.getDBDictionaryInstance().addDelimiters(_seqName), _seq);
}
@Override
@ -208,8 +210,8 @@ public class NativeJDBCSeq
if (_format == null)
throw new MetaDataException(_loc.get("no-seq-sql", _seqName));
}
if (_tableName == null)
_tableName = "DUAL";
if (DBIdentifier.isNull(_tableName))
_tableName = DBIdentifier.newTable("DUAL");
String name = dict.getFullName(_seq);
Object[] subs = (_subTable) ? new Object[]{ name, _tableName }
@ -234,17 +236,18 @@ public class NativeJDBCSeq
* Creates the sequence object.
*/
private void buildSequence() {
String seqName = Strings.getClassName(_seqName);
QualifiedDBIdentifier path = QualifiedDBIdentifier.getPath(_seqName);
DBIdentifier seqName = path.getIdentifier();
// JPA 2 added schema as a configurable attribute on
// sequence generator. OpenJPA <= 1.x allowed this via
// schema.sequence on the sequence name. Specifying a schema
// name on the annotation or in the orm will override the old
// behavior.
String schemaName = _schema;
if (schemaName == null || schemaName.length() == 0) {
schemaName = Strings.getPackageName(_seqName);
if (schemaName.length() == 0)
schemaName = Schemas.getNewTableSchema(_conf);
DBIdentifier schemaName = _schema;
if (DBIdentifier.isEmpty(schemaName)) {
schemaName = path.getSchemaName();
if (DBIdentifier.isEmpty(schemaName))
schemaName = Schemas.getNewTableSchemaIdentifier(_conf);
}
// build the sequence in one of the designated schemas
@ -252,8 +255,6 @@ public class NativeJDBCSeq
Schema schema = group.addSchema(schemaName);
_seq = schema.addSequence(seqName);
// TODO: temp until a global name solution is implemented
schema.addDelimSequenceName(_conf.getDBDictionaryInstance().addDelimiters(seqName), _seq);
_seq.setInitialValue(_initial);
_seq.setIncrement(_increment);
_seq.setAllocate(_allocate);
@ -402,11 +403,22 @@ public class NativeJDBCSeq
return true;
}
public void setSchema(String _schema) {
this._schema = _schema;
/**
* @deprecated
*/
public void setSchema(String schema) {
_schema = DBIdentifier.newSchema(schema);
}
/**
* @deprecated
*/
public String getSchema() {
return _schema.getName();
}
public DBIdentifier getSchemaIdentifier() {
return _schema;
}
}

View File

@ -29,6 +29,8 @@ import java.util.LinkedList;
import java.util.List;
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.identifier.DBIdentifier.DBIdentifierType;
import org.apache.openjpa.jdbc.meta.ClassMapping;
import org.apache.openjpa.jdbc.meta.FieldMapping;
import org.apache.openjpa.jdbc.schema.Column;
@ -167,10 +169,10 @@ public class PreparedStatementManagerImpl
* from the result set associated with the stmnt. If not, a separate
* sql to select the key will be issued from DBDictionary.
*/
protected List populateAutoAssignCols(PreparedStatement stmnt,
Column[] autoAssign, String[] autoAssignColNames, RowImpl row)
protected List<Object> populateAutoAssignCols(PreparedStatement stmnt,
Column[] autoAssign, DBIdentifier[] autoAssignColNames, RowImpl row)
throws SQLException {
List vals = null;
List<Object> vals = null;
if (_dict.supportsGetGeneratedKeys) {
// set auto assign values to id col
vals = getGeneratedKeys(stmnt, autoAssignColNames);
@ -179,9 +181,22 @@ public class PreparedStatementManagerImpl
return vals;
}
protected List<Object> populateAutoAssignCols(PreparedStatement stmnt,
Column[] autoAssign, String[] autoAssignColNames, RowImpl row)
throws SQLException {
return populateAutoAssignCols(stmnt, autoAssign,
DBIdentifier.toArray(autoAssignColNames, DBIdentifierType.COLUMN), row);
}
protected void setObjectId(List vals, Column[] autoAssign,
String[] autoAssignColNames, RowImpl row)
throws SQLException{
setObjectId(vals, autoAssign, DBIdentifier.toArray(autoAssignColNames, DBIdentifierType.COLUMN), row);
}
protected void setObjectId(List vals, Column[] autoAssign,
DBIdentifier[] autoAssignColNames, RowImpl row)
throws SQLException{
OpenJPAStateManager sm = row.getPrimaryKey();
ClassMapping mapping = (ClassMapping) sm.getMetaData();
Object val = null;
@ -202,9 +217,15 @@ public class PreparedStatementManagerImpl
* This method will only be called when the database supports
* getGeneratedKeys.
*/
protected List getGeneratedKeys(PreparedStatement stmnt,
protected List<Object> getGeneratedKeys(PreparedStatement stmnt,
String[] autoAssignColNames)
throws SQLException {
return getGeneratedKeys(stmnt, DBIdentifier.toArray(autoAssignColNames, DBIdentifierType.COLUMN));
}
protected List<Object> getGeneratedKeys(PreparedStatement stmnt,
DBIdentifier[] autoAssignColNames)
throws SQLException {
ResultSet rs = stmnt.getGeneratedKeys();
List<Object> vals = new ArrayList<Object>();
while (rs.next()) {
@ -222,14 +243,22 @@ public class PreparedStatementManagerImpl
return autoAssign;
}
/**
* @deprecated
*/
protected String[] getAutoAssignColNames(Column[] autoAssign, RowImpl row) {
String[] autoAssignColNames = null;
DBIdentifier[] names = getAutoAssignColIdentifiers(autoAssign, row);
return DBIdentifier.toStringArray(names);
}
protected DBIdentifier[] getAutoAssignColIdentifiers(Column[] autoAssign, RowImpl row) {
DBIdentifier[] autoAssignColNames = null;
if (autoAssign != null && autoAssign.length > 0
&& row.getPrimaryKey() != null) {
autoAssignColNames = new String[autoAssign.length];
autoAssignColNames = new DBIdentifier[autoAssign.length];
for (int i = 0; i < autoAssign.length; i++)
autoAssignColNames[i] =
_dict.convertSchemaCase(autoAssign[i].getName());
autoAssignColNames[i] = autoAssign[i].getIdentifier();
// _dict.convertSchemaCase(.getName());
}
return autoAssignColNames;
}

View File

@ -31,6 +31,10 @@ import javax.transaction.NotSupportedException;
import org.apache.commons.lang.StringUtils;
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
import org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl;
import org.apache.openjpa.jdbc.identifier.Normalizer;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.identifier.QualifiedDBIdentifier;
import org.apache.openjpa.jdbc.identifier.DBIdentifier.DBIdentifierType;
import org.apache.openjpa.jdbc.meta.ClassMapping;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.PrimaryKey;
@ -46,6 +50,7 @@ import org.apache.openjpa.jdbc.sql.SQLBuffer;
import org.apache.openjpa.lib.conf.Configurable;
import org.apache.openjpa.lib.conf.Configuration;
import org.apache.openjpa.lib.conf.Configurations;
import org.apache.openjpa.lib.identifier.IdentifierUtil;
import org.apache.openjpa.lib.log.Log;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.lib.util.Options;
@ -54,7 +59,6 @@ import org.apache.openjpa.util.InvalidStateException;
import org.apache.openjpa.util.UserException;
import serp.util.Numbers;
import serp.util.Strings;
////////////////////////////////////////////////////////////
// NOTE: Do not change property names; see SequenceMetaData
@ -88,11 +92,11 @@ public class TableJDBCSeq
private final HashMap<ClassMapping, Status> _stat =
new HashMap<ClassMapping, Status>();
private String _table = DEFAULT_TABLE;
private String _seqColumnName = "SEQUENCE_VALUE";
private String _pkColumnName = "ID";
private String[] _uniqueColumnNames;
private String _uniqueConstraintName;
private DBIdentifier _table = DBIdentifier.newTable(DEFAULT_TABLE);
private DBIdentifier _seqColumnName = DBIdentifier.newColumn("SEQUENCE_VALUE");
private DBIdentifier _pkColumnName = DBIdentifier.newColumn("ID");
private DBIdentifier[] _uniqueColumnNames;
private DBIdentifier _uniqueConstraintName = DBIdentifier.NULL;
private Column _seqColumn = null;
private Column _pkColumn = null;
@ -106,7 +110,7 @@ public class TableJDBCSeq
* will be used.
*/
public String getTable() {
return _table;
return _table.getName();
}
/**
@ -118,7 +122,10 @@ public class TableJDBCSeq
* will be used.
*/
public void setTable(String name) {
_table = name;
// Split the name into its individual parts
String[] names = Normalizer.splitName(name);
// Join the name back together. This will delimit as appropriate.
_table = DBIdentifier.newTable(Normalizer.joinNames(names));
}
/**
@ -134,7 +141,7 @@ public class TableJDBCSeq
* to <code>SEQUENCE_VALUE</code>.
*/
public String getSequenceColumn() {
return _seqColumnName;
return _seqColumnName.getName();
}
/**
@ -142,7 +149,7 @@ public class TableJDBCSeq
* to <code>SEQUENCE_VALUE</code>.
*/
public void setSequenceColumn(String sequenceColumn) {
_seqColumnName = sequenceColumn;
_seqColumnName = DBIdentifier.newColumn(sequenceColumn);
}
/**
@ -150,6 +157,10 @@ public class TableJDBCSeq
* <code>ID</code>.
*/
public String getPrimaryKeyColumn() {
return _pkColumnName.getName();
}
public DBIdentifier getPrimaryKeyColumnIdentifier() {
return _pkColumnName;
}
@ -158,7 +169,7 @@ public class TableJDBCSeq
* <code>ID</code>.
*/
public void setPrimaryKeyColumn(String primaryKeyColumn) {
_pkColumnName = primaryKeyColumn;
_pkColumnName = DBIdentifier.newColumn(primaryKeyColumn);
}
/**
@ -186,7 +197,7 @@ public class TableJDBCSeq
* GeneratedValue.TABLE strategy to start with.
* @return an initial number
*/
public int getInitialValue() {
public int getInitialValue() {
return _intValue;
}
@ -206,11 +217,11 @@ public class TableJDBCSeq
*/
public void setUniqueColumns(String columnNames) {
_uniqueColumnNames = (StringUtils.isEmpty(columnNames))
? null : StringUtils.split(columnNames, '|');
? null : DBIdentifier.split(columnNames, DBIdentifierType.COLUMN, IdentifierUtil.BAR);
}
public String getUniqueColumns() {
return StringUtils.join(_uniqueColumnNames, '|');
return Normalizer.joinNames(DBIdentifier.toStringArray(_uniqueColumnNames), IdentifierUtil.BAR);
}
/**
@ -245,16 +256,20 @@ public class TableJDBCSeq
Schema[] schemas = group.getSchemas();
for (int i = 0; i < schemas.length; i++) {
String schemaName = Strings.getPackageName(_table);
if (schemaName.length() == 0)
schemaName = Schemas.getNewTableSchema(_conf);
if (schemaName == null)
schemaName = schemas[i].getName();
QualifiedDBIdentifier path = QualifiedDBIdentifier.getPath(_table);
DBIdentifier schemaName = path.getSchemaName();
if (DBIdentifier.isEmpty(schemaName)) {
schemaName = Schemas.getNewTableSchemaIdentifier(_conf);
}
if (DBIdentifier.isNull(schemaName)) {
schemaName = schemas[i].getIdentifier();
}
// create table in this group
Schema schema = group.getSchema(schemaName);
if (schema == null)
if (schema == null) {
schema = group.addSchema(schemaName);
}
Table copy = schema.importTable(_pkColumn.getTable());
// importTable() does not import unique constraints
@ -265,8 +280,7 @@ public class TableJDBCSeq
// we need to reset the table name in the column with the
// fully qualified name for matching the table name from the
// Column.
_pkColumn.resetTableName(schemaName + "."
+ _pkColumn.getTableName());
_pkColumn.resetTableIdentifier(QualifiedDBIdentifier.newPath(schemaName, _pkColumn.getTableIdentifier()));
// some databases require to create an index for the sequence table
_conf.getDBDictionaryInstance().createIndexIfNecessary(schema,
_table, _pkColumn);
@ -351,7 +365,7 @@ public class TableJDBCSeq
protected Column addPrimaryKeyColumn(Table table) {
DBDictionary dict = _conf.getDBDictionaryInstance();
Column pkColumn = table.addColumn(dict.getValidColumnName
(getPrimaryKeyColumn(), table));
(getPrimaryKeyColumnIdentifier(), table));
pkColumn.setType(dict.getPreferredType(Types.TINYINT));
pkColumn.setJavaType(JavaTypes.INT);
return pkColumn;
@ -368,20 +382,20 @@ public class TableJDBCSeq
* Creates the object-level representation of the sequence table.
*/
private void buildTable() {
String tableName = null;
String schemaName = "";
if (StringUtils.contains(_table,'.')) {
String[] tableParts = StringUtils.split(_table, '.');
// TODO: do we need to check for length? Could we have xxx. or .xxx?
schemaName = tableParts[0];
tableName = tableParts[1];
DBIdentifier tableName = DBIdentifier.NULL;
DBIdentifier schemaName = DBIdentifier.NULL;
QualifiedDBIdentifier path = QualifiedDBIdentifier.getPath(_table);
if (!DBIdentifier.isEmpty(path.getSchemaName())) {
schemaName = path.getSchemaName();
tableName = path.getUnqualifiedName();
}
else {
tableName = _table;
}
if (schemaName.length() == 0)
schemaName = Schemas.getNewTableSchema(_conf);
if (DBIdentifier.isEmpty(schemaName)) {
schemaName = Schemas.getNewTableSchemaIdentifier(_conf);
}
SchemaGroup group = new SchemaGroup();
Schema schema = group.addSchema(schemaName);
@ -398,17 +412,17 @@ public class TableJDBCSeq
_seqColumn.setJavaType(JavaTypes.LONG);
if (_uniqueColumnNames != null) {
String uniqueName = _uniqueConstraintName;
if (StringUtils.isEmpty(uniqueName)) {
uniqueName = dict.getValidUniqueName("UNQ", table);
DBIdentifier uniqueName = _uniqueConstraintName;
if (DBIdentifier.isEmpty(uniqueName)) {
uniqueName = dict.getValidUniqueName(DBIdentifier.newConstraint("UNQ"), table);
}
Unique u = table.addUnique(uniqueName);
for (String columnName : _uniqueColumnNames) {
for (DBIdentifier columnName : _uniqueColumnNames) {
if (!table.containsColumn(columnName, _conf.getDBDictionaryInstance()))
throw new UserException(_loc.get("unique-missing-column",
columnName, table.getName(),
columnName, table.getIdentifier(),
table.getColumnNames()));
Column col = table.getColumn(columnName, _conf.getDBDictionaryInstance());
Column col = table.getColumn(columnName);
u.addColumn(col);
}
}
@ -469,7 +483,7 @@ public class TableJDBCSeq
getClass(), mapping));
DBDictionary dict = _conf.getDBDictionaryInstance();
String tableName = resolveTableName(mapping, _pkColumn.getTable());
DBIdentifier tableName = resolveTableIdentifier(mapping, _pkColumn.getTable());
SQLBuffer insert = new SQLBuffer(dict).append("INSERT INTO ").
append(tableName).append(" (").
append(_pkColumn).append(", ").append(_seqColumn).
@ -519,7 +533,7 @@ public class TableJDBCSeq
SQLBuffer sel = new SQLBuffer(dict).append(_seqColumn);
SQLBuffer where = new SQLBuffer(dict).append(_pkColumn).append(" = ").
appendValue(pk, _pkColumn);
String tableName = resolveTableName(mapping, _seqColumn.getTable());
DBIdentifier tableName = resolveTableIdentifier(mapping, _seqColumn.getTable());
SQLBuffer tables = new SQLBuffer(dict).append(tableName);
SQLBuffer select = dict.toSelect(sel, null, tables, where, null, null,
@ -577,7 +591,7 @@ public class TableJDBCSeq
// update the value
upd = new SQLBuffer(dict);
String tableName = resolveTableName(mapping,
DBIdentifier tableName = resolveTableIdentifier(mapping,
_seqColumn.getTable());
upd.append("UPDATE ").append(tableName).
append(" SET ").append(_seqColumn).append(" = ").
@ -612,19 +626,32 @@ public class TableJDBCSeq
*
* @param class
* mapping to get the schema name
* @deprecated
*/
public String resolveTableName(ClassMapping mapping, Table table) {
String sName = mapping.getTable().getSchemaName();
String tableName;
if (sName == null)
tableName = table.getFullName();
else if (table.getSchemaName() != null)
tableName = table.getFullName();
else
tableName = sName + "." + table.getName();
return resolveTableIdentifier(mapping, table).getName();
}
/**
* Resolve a fully qualified table name
*
* @param class
* mapping to get the schema name
*/
public DBIdentifier resolveTableIdentifier(ClassMapping mapping, Table table) {
DBIdentifier sName = mapping.getTable().getSchemaIdentifier();
DBIdentifier tableName = DBIdentifier.NULL;
if (DBIdentifier.isNull(sName)) {
tableName = table.getFullIdentifier();
} else if (!DBIdentifier.isNull(table.getSchemaIdentifier())) {
tableName = table.getFullIdentifier();
} else {
tableName = QualifiedDBIdentifier.newPath(sName, table.getIdentifier());
}
return tableName;
}
/**
* Creates the sequence table in the DB.
*/
@ -763,6 +790,7 @@ public class TableJDBCSeq
/**
* Helper struct to hold status information.
*/
@SuppressWarnings("serial")
protected static class Status
implements Serializable {
@ -809,11 +837,19 @@ public class TableJDBCSeq
return dict.getLong(rs, 1);
}
public void setUniqueConstraintName(String _uniqueConstraintName) {
this._uniqueConstraintName = _uniqueConstraintName;
public void setUniqueConstraintName(String uniqueConstraintName) {
_uniqueConstraintName = DBIdentifier.newConstraint(uniqueConstraintName);
}
public void setUniqueConstraintName(DBIdentifier uniqueConstraintName) {
_uniqueConstraintName = uniqueConstraintName;
}
public String getUniqueConstraintName() {
return _uniqueConstraintName.getName();
}
public DBIdentifier getUniqueConstraintIdentifier() {
return _uniqueConstraintName;
}

View File

@ -78,7 +78,7 @@ public class ValueTableJDBCSeq
protected Column addPrimaryKeyColumn(Table table) {
DBDictionary dict = getConfiguration().getDBDictionaryInstance();
Column pkColumn = table.addColumn(dict.getValidColumnName
(getPrimaryKeyColumn(), table));
(getPrimaryKeyColumnIdentifier(), table));
pkColumn.setType(dict.getPreferredType(Types.VARCHAR));
pkColumn.setJavaType(JavaTypes.STRING);
pkColumn.setSize(dict.characterColumnSize);

View File

@ -979,7 +979,7 @@ public class PCPath
// if select is null, it means we are not aliasing columns
// (e.g., during a bulk update)
if (sel == null)
sql.append(col.getName());
sql.append(col.getIdentifier());
else if (_type == XPATH)
// if this is an xpath, append xpath string
sql.append(getXPath());

View File

@ -281,7 +281,7 @@ public class ClassMapping
Joinable join = getJoinable(col);
if (join == null)
throw new MetaDataException(_loc.get("no-joinable",
col.getFullName()));
col.getQualifiedPath().toString()));
return join;
}

View File

@ -29,7 +29,8 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.lang.StringUtils;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.identifier.QualifiedDBIdentifier;
import org.apache.openjpa.jdbc.meta.strats.FullClassStrategy;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.ForeignKey;
@ -51,6 +52,7 @@ import org.apache.openjpa.util.UserException;
*
* @author Abe White
*/
@SuppressWarnings("serial")
public class ClassMappingInfo
extends MappingInfo
implements SourceTracker, Commentable {
@ -59,10 +61,10 @@ public class ClassMappingInfo
(ClassMappingInfo.class);
private String _className = Object.class.getName();
private String _tableName = null;
private String _schemaName = null;
private DBIdentifier _tableName = DBIdentifier.NULL;
private DBIdentifier _schemaName = DBIdentifier.NULL;
private boolean _joined = false;
private Map _seconds = null;
private Map<DBIdentifier, List<Column>> _seconds = null;
private String _subStrat = null;
private File _file = null;
private int _srcType = SRC_OTHER;
@ -71,7 +73,7 @@ public class ClassMappingInfo
private int _colNum = 0;
// Unique constraints indexed by primary or secondary table name
private Map<String,List<Unique>> _uniques;
private Map<DBIdentifier,List<Unique>> _uniques;
/**
* The described class name.
@ -103,29 +105,49 @@ public class ClassMappingInfo
/**
* The given table name.
* @deprecated
*/
public String getTableName() {
return _tableName;
return getTableIdentifier().getName();
}
public DBIdentifier getTableIdentifier() {
return _tableName == null ? DBIdentifier.NULL : _tableName;
}
/**
* The given table name.
* @deprecated
*/
public void setTableName(String table) {
setTableIdentifier(DBIdentifier.newTable(table));
}
public void setTableIdentifier(DBIdentifier table) {
_tableName = table;
}
/**
* The default schema name for unqualified tables.
* @deprecated
*/
public String getSchemaName() {
return _schemaName;
return getSchemaIdentifier().getName();
}
public DBIdentifier getSchemaIdentifier() {
return _schemaName == null ? DBIdentifier.NULL : _schemaName;
}
/**
* The default schema name for unqualified tables.
* @deprecated
*/
public void setSchemaName(String schema) {
setSchemaIdentifier(DBIdentifier.newSchema(schema));
}
public void setSchemaIdentifier(DBIdentifier schema) {
_schemaName = schema;
}
@ -145,11 +167,18 @@ public class ClassMappingInfo
/**
* Return the class-level joined tables.
* @deprecated
*/
public String[] getSecondaryTableNames() {
if (_seconds == null)
return new String[0];
return (String[]) _seconds.keySet().toArray(new String[]{ });
return DBIdentifier.toStringArray(_seconds.keySet().toArray(new DBIdentifier[]{ }));
}
public DBIdentifier[] getSecondaryTableIdentifiers() {
if (_seconds == null)
return new DBIdentifier[0];
return (DBIdentifier[]) _seconds.keySet().toArray(new DBIdentifier[]{ });
}
/**
@ -157,33 +186,38 @@ public class ClassMappingInfo
* name, whereas the class join might have schema, etc information.
* This method returns the name of the given table as listed in a
* class-level join, or the given name if no join exists.
* @deprecated
*/
public String getSecondaryTableName(String tableName) {
return getSecondaryTableIdentifier(DBIdentifier.newTable(tableName)).getName();
}
public DBIdentifier getSecondaryTableIdentifier(DBIdentifier tableName) {
// if no secondary table joins, bad table name, exact match,
// or an already-qualified table name, nothing to do
if (_seconds == null || tableName == null
QualifiedDBIdentifier path = QualifiedDBIdentifier.getPath(tableName);
if (_seconds == null || DBIdentifier.isNull(tableName)
|| _seconds.containsKey(tableName)
|| tableName.indexOf('.') != -1)
|| !DBIdentifier.isNull(path.getSchemaName()))
return tableName;
// decide which class-level join table is best match
String best = tableName;
DBIdentifier best = tableName;
int pts = 0;
String fullJoin;
String join;
int idx;
for (Iterator itr = _seconds.keySet().iterator(); itr.hasNext();) {
DBIdentifier fullJoin = DBIdentifier.NULL;
DBIdentifier join = DBIdentifier.NULL;
for (Iterator<DBIdentifier> itr = _seconds.keySet().iterator(); itr.hasNext();) {
// award a caseless match without schema 2 points
fullJoin = (String) itr.next();
idx = fullJoin.lastIndexOf('.');
if (idx == -1 && pts < 2 && fullJoin.equalsIgnoreCase(tableName)) {
fullJoin = (DBIdentifier) itr.next();
QualifiedDBIdentifier joinPath = QualifiedDBIdentifier.getPath(fullJoin);
if (joinPath.isUnqualifiedObject() && pts < 2 && fullJoin.equalsIgnoreCase(tableName)) {
best = fullJoin;
pts = 2;
} else if (idx == -1)
} else if (joinPath.isUnqualifiedObject())
continue;
// immediately return an exact match with schema
join = fullJoin.substring(idx + 1);
join = joinPath.getIdentifier();
if (join.equals(tableName))
return fullJoin;
@ -199,48 +233,78 @@ public class ClassMappingInfo
/**
* Return any columns defined for the given class level join, or empty
* list if none.
* @deprecated
*/
public List getSecondaryTableJoinColumns(String tableName) {
if (_seconds == null || tableName == null)
return Collections.EMPTY_LIST;
public List<Column> getSecondaryTableJoinColumns(String tableName) {
return getSecondaryTableJoinColumns(DBIdentifier.newTable(tableName));
}
public List<Column> getSecondaryTableJoinColumns(DBIdentifier tableName) {
if (_seconds == null || DBIdentifier.isNull(tableName)) {
return Collections.emptyList();
}
// get the columns for the join with the best match for table name
List cols = (List) _seconds.get(getSecondaryTableName(tableName));
List<Column> cols = _seconds.get(getSecondaryTableIdentifier(tableName));
if (cols == null) {
// possible that given table has extra info the join table
// doesn't have; strip it
int idx = tableName.lastIndexOf('.');
if (idx != -1) {
tableName = tableName.substring(idx + 1);
cols = (List) _seconds.get(getSecondaryTableName(tableName));
QualifiedDBIdentifier path = QualifiedDBIdentifier.getPath(tableName);
if (!DBIdentifier.isNull(path.getSchemaName())) {
tableName = path.getIdentifier();
cols = _seconds.get(getSecondaryTableIdentifier(tableName));
}
}
return (cols == null) ? Collections.EMPTY_LIST : cols;
if (cols == null) {
return Collections.emptyList();
}
return cols;
}
/**
* Adds a Secondary table of given name to this mapping. A secondary table
* must be known before unique constraints are added to a Secondary table.
* @deprecated
*/
public void addSecondaryTable(String second) {
setSecondaryTableJoinColumns(second, null);
setSecondaryTableJoinColumns(DBIdentifier.newTable(second), null);
}
public void addSecondaryTable(DBIdentifier second) {
setSecondaryTableJoinColumns(second, null);
}
/**
* Declare the given class-level join to the named (secondary) table.
* @deprecated
*/
public void setSecondaryTableJoinColumns(String tableName, List cols) {
public void setSecondaryTableJoinColumns(String tableName, List<Column> cols) {
if (cols == null)
cols = Collections.EMPTY_LIST;
cols = Collections.emptyList();
setSecondaryTableJoinColumns(DBIdentifier.newTable(tableName), cols);
}
public void setSecondaryTableJoinColumns(DBIdentifier tableName, List<Column> cols) {
if (cols == null)
cols = Collections.emptyList();
if (_seconds == null)
_seconds = new LinkedHashMap();
_seconds = new LinkedHashMap<DBIdentifier, List<Column>>();
_seconds.put(tableName, cols);
}
/**
* Return the named table for the given class.
* @deprecated
*/
public Table getTable(final ClassMapping cls, String tableName,
boolean adapt) {
return getTable(cls, DBIdentifier.newTable(tableName), adapt);
}
/**
* Return the named table for the given class.
*/
public Table getTable(final ClassMapping cls, DBIdentifier tableName,
boolean adapt) {
Table t = createTable(cls, new TableDefaults() {
public String get(Schema schema) {
@ -249,6 +313,10 @@ public class ClassMappingInfo
return cls.getMappingRepository().getMappingDefaults().
getTableName(cls, schema);
}
public DBIdentifier getIdentifier(Schema schema) {
return cls.getMappingRepository().getMappingDefaults().
getTableIdentifier(cls, schema);
}
}, _schemaName, tableName, adapt);
t.setComment(cls.getTypeAlias() == null
? cls.getDescribedType().getName()
@ -312,7 +380,7 @@ public class ClassMappingInfo
if (cls.getTable() != null && (sup == null
|| sup.getTable() != cls.getTable()))
_tableName = cls.getMappingRepository().getDBDictionary().
getFullName(cls.getTable(), true);
getFullIdentifier(cls.getTable(), true);
// set io before syncing cols
setColumnIO(cls.getColumnIO());
@ -334,12 +402,12 @@ public class ClassMappingInfo
}
public boolean hasSchemaComponents() {
return super.hasSchemaComponents() || _tableName != null;
return super.hasSchemaComponents() || !DBIdentifier.isNull(_tableName);
}
protected void clear(boolean canFlags) {
super.clear(canFlags);
_tableName = null;
_tableName = DBIdentifier.NULL;
}
public void copy(MappingInfo info) {
@ -348,15 +416,15 @@ public class ClassMappingInfo
return;
ClassMappingInfo cinfo = (ClassMappingInfo) info;
if (_tableName == null)
_tableName = cinfo.getTableName();
if (DBIdentifier.isNull(_tableName))
_tableName = cinfo.getTableIdentifier();
if (_subStrat == null)
_subStrat = cinfo.getHierarchyStrategy();
if (cinfo._seconds != null) {
if (_seconds == null)
_seconds = new HashMap();
Object key;
for (Iterator itr = cinfo._seconds.keySet().iterator();
_seconds = new HashMap<DBIdentifier, List<Column>>();
DBIdentifier key;
for (Iterator<DBIdentifier> itr = cinfo._seconds.keySet().iterator();
itr.hasNext();) {
key = itr.next();
if (!_seconds.containsKey(key))
@ -365,8 +433,8 @@ public class ClassMappingInfo
}
if (cinfo._uniques != null) {
if (_uniques == null)
_uniques = new HashMap<String, List<Unique>>();
for (Entry<String, List<Unique>> entry : cinfo._uniques.entrySet())
_uniques = new HashMap<DBIdentifier, List<Unique>>();
for (Entry<DBIdentifier, List<Unique>> entry : cinfo._uniques.entrySet())
if (!_uniques.containsKey(entry.getKey()))
_uniques.put(entry.getKey(), entry.getValue());
}
@ -378,9 +446,20 @@ public class ClassMappingInfo
* @param table must be primary table or secondary table name added a
* priori to this receiver.
* @param unique the unique constraint. null means no-op.
* @deprecated
*/
public void addUnique(String table, Unique unique) {
if (!StringUtils.equals(_tableName, table) &&
addUnique(DBIdentifier.newTable(table), unique);
}
/**
* Add a unique constraint for the given table.
* @param table must be primary table or secondary table name added a
* priori to this receiver.
* @param unique the unique constraint. null means no-op.
*/
public void addUnique(DBIdentifier table, Unique unique) {
if (!DBIdentifier.equal(_tableName, table) &&
(_seconds == null || !_seconds.containsKey(table))) {
throw new UserException(_loc.get("unique-no-table",
new Object[]{table, _className, _tableName,
@ -389,8 +468,8 @@ public class ClassMappingInfo
if (unique == null)
return;
if (_uniques == null)
_uniques = new HashMap<String,List<Unique>>();
unique.setTableName(table);
_uniques = new HashMap<DBIdentifier,List<Unique>>();
unique.setTableIdentifier(table);
List<Unique> uniques = _uniques.get(table);
if (uniques == null) {
uniques = new ArrayList<Unique>();
@ -403,8 +482,16 @@ public class ClassMappingInfo
/**
* Get the unique constraints of the given primary or secondary table.
* @deprecated
*/
public Unique[] getUniques(String table) {
return getUniques(DBIdentifier.newTable(table));
}
/**
* Get the unique constraints of the given primary or secondary table.
*/
public Unique[] getUniques(DBIdentifier table) {
if (_uniques == null || _uniques.isEmpty()
|| _uniques.containsKey(table))
return new Unique[0];
@ -421,14 +508,14 @@ public class ClassMappingInfo
if (_uniques == null || _uniques.isEmpty())
return new Unique[0];
List<Unique> result = new ArrayList<Unique>();
for (String tableName : _uniques.keySet()) {
for (DBIdentifier tableName : _uniques.keySet()) {
List<Unique> uniqueConstraints = _uniques.get(tableName);
for (Unique template : uniqueConstraints) {
Column[] templateColumns = template.getColumns();
Column[] uniqueColumns = new Column[templateColumns.length];
Table table = getTable((ClassMapping)cm, tableName, adapt);
for (int i=0; i<uniqueColumns.length; i++) {
String columnName = templateColumns[i].getName();
DBIdentifier columnName = templateColumns[i].getIdentifier();
if (!table.containsColumn(columnName)) {
throw new UserException(_loc.get(
"unique-missing-column",
@ -491,5 +578,4 @@ public class ClassMappingInfo
public void setColNumber(int colNum) {
_colNum = colNum;
}
}

View File

@ -107,7 +107,7 @@ public interface ClassStrategy
/**
* Implement this method to customize loading from a {@link Result}
* into an instance. Return true if this mapping handles the
* load; false if normal loading should procede after calling this method.
* load; false if normal loading should proceed after calling this method.
*/
public boolean customLoad(OpenJPAStateManager sm, JDBCStore store,
JDBCFetchConfiguration fetch, Result result)

View File

@ -41,6 +41,7 @@ import org.apache.openjpa.util.MetaDataException;
*
* @author Abe White
*/
@SuppressWarnings("serial")
public class DelegatingJoinable
implements Joinable {
@ -68,7 +69,7 @@ public class DelegatingJoinable
_cols[i] = fk.getColumn(pks[i]);
if (_cols[i] == null)
throw new MetaDataException(_loc.get("incomplete-join",
pks[i].getFullName()));
pks[i].getFullDBIdentifier()));
}
}
@ -84,7 +85,7 @@ public class DelegatingJoinable
_cols = cols;
if (cols.length != join.getColumns().length)
throw new MetaDataException(_loc.get("bad-remap",
join.getColumns()[0].getFullName()));
join.getColumns()[0].getFullDBIdentifier()));
}
public int getFieldIndex() {

View File

@ -33,7 +33,6 @@ import org.apache.openjpa.jdbc.sql.Select;
import org.apache.openjpa.kernel.OpenJPAStateManager;
import org.apache.openjpa.lib.log.Log;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.meta.JavaTypes;
import org.apache.openjpa.meta.MetaDataContext;
import org.apache.openjpa.meta.MetaDataModes;
import org.apache.openjpa.meta.MetaDataRepository;
@ -44,6 +43,7 @@ import org.apache.openjpa.util.InternalException;
*
* @author Abe White
*/
@SuppressWarnings("serial")
public class Discriminator
implements DiscriminatorStrategy, MetaDataContext, MetaDataModes {
@ -393,7 +393,7 @@ public class Discriminator
assertStrategy().loadSubclasses(store);
}
public Class getClass(JDBCStore store, ClassMapping base, Result result)
public Class<?> getClass(JDBCStore store, ClassMapping base, Result result)
throws SQLException, ClassNotFoundException {
return assertStrategy().getClass(store, base, result);
}

View File

@ -28,9 +28,7 @@ import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.Index;
import org.apache.openjpa.jdbc.schema.SchemaGroup;
import org.apache.openjpa.jdbc.schema.Table;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.meta.JavaTypes;
import org.apache.openjpa.util.MetaDataException;
/**
* Information about the mapping from a discriminator to the schema, in
@ -40,12 +38,10 @@ import org.apache.openjpa.util.MetaDataException;
*
* @author Abe White
*/
@SuppressWarnings("serial")
public class DiscriminatorMappingInfo
extends MappingInfo {
private static final Localizer _loc = Localizer.forPackage
(DiscriminatorMappingInfo.class);
private String _value = null;
/**

View File

@ -58,7 +58,7 @@ public interface DiscriminatorStrategy
/**
* Return the class for the current result row.
*/
public Class getClass(JDBCStore store, ClassMapping base, Result result)
public Class<?> getClass(JDBCStore store, ClassMapping base, Result result)
throws SQLException, ClassNotFoundException;
/**

View File

@ -23,6 +23,7 @@ import java.util.List;
import org.apache.openjpa.enhance.PersistenceCapable;
import org.apache.openjpa.enhance.Reflection;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
import org.apache.openjpa.jdbc.kernel.JDBCStore;
import org.apache.openjpa.jdbc.meta.strats.NoneFieldStrategy;
@ -58,6 +59,7 @@ import org.apache.openjpa.util.ObjectId;
*
* @author Abe White
*/
@SuppressWarnings("serial")
public class FieldMapping
extends FieldMetaData
implements ValueMapping, FieldStrategy {
@ -98,7 +100,7 @@ public class FieldMapping
/**
* Constructor.
*/
public FieldMapping(String name, Class type, ClassMapping owner) {
public FieldMapping(String name, Class<?> type, ClassMapping owner) {
super(name, type, owner);
_info = owner.getMappingRepository().newMappingInfo(this);
_val = (ValueMapping) getValue();
@ -623,7 +625,7 @@ public class FieldMapping
private void setPKValueFromMappedByIdField(OpenJPAStateManager sm) {
if (sm instanceof StateManagerImpl) {
List mappedByIdFields = ((StateManagerImpl)sm).
List<FieldMetaData> mappedByIdFields = ((StateManagerImpl)sm).
getMappedByIdFields();
if (mappedByIdFields == null)
return;
@ -1161,10 +1163,17 @@ public class FieldMapping
_val.setPolymorphic(poly);
}
/**
* @deprecated
*/
public void mapConstraints(String name, boolean adapt) {
_val.mapConstraints(name, adapt);
}
public void mapConstraints(DBIdentifier name, boolean adapt) {
_val.mapConstraints(name, adapt);
}
public void copyMappingInfo(ValueMapping vm) {
_val.copyMappingInfo(vm);
}
@ -1326,7 +1335,7 @@ public class FieldMapping
if (mapped != null) {
FieldMappingInfo info = getMappingInfo();
FieldMappingInfo mappedInfo = mapped.getMappingInfo();
info.setTableName(mappedInfo.getTableName());
info.setTableIdentifier(mappedInfo.getTableIdentifier());
info.setColumns(mapped.getElementMapping().getValueInfo().getColumns());
getElementMapping().getValueInfo().setColumns(
mappedInfo.getColumns());

View File

@ -22,8 +22,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.apache.openjpa.conf.Compatibility;
import org.apache.openjpa.jdbc.meta.strats.MapTableFieldStrategy;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.ColumnIO;
import org.apache.openjpa.jdbc.schema.ForeignKey;
@ -47,6 +46,7 @@ import org.apache.openjpa.util.MetaDataException;
* @author Abe White
* @author Pinaki Poddar
*/
@SuppressWarnings("serial")
public class FieldMappingInfo
extends MappingInfo
implements Commentable {
@ -54,7 +54,7 @@ public class FieldMappingInfo
private static final Localizer _loc = Localizer.forPackage
(FieldMappingInfo.class);
private String _tableName = null;
private DBIdentifier _tableName = DBIdentifier.NULL;
private boolean _outer = false;
private Column _orderCol = null;
private boolean _canOrderCol = true;
@ -63,15 +63,25 @@ public class FieldMappingInfo
/**
* The user-supplied name of the table for this field.
* @deprecated
*/
public String getTableName() {
return _tableName;
return getTableIdentifier().getName();
}
public DBIdentifier getTableIdentifier() {
return _tableName == null ? DBIdentifier.NULL : _tableName;
}
/**
* The user-supplied name of the table for this field.
* @deprecated
*/
public void setTableName(String tableName) {
setTableIdentifier(DBIdentifier.newTable(tableName));
}
public void setTableIdentifier(DBIdentifier tableName) {
_tableName = tableName;
}
@ -124,19 +134,19 @@ public class FieldMappingInfo
*/
public Table getTable(final FieldMapping field, boolean create,
boolean adapt) {
if (_tableName == null && !create)
if (DBIdentifier.isNull(_tableName) && !create)
return null;
Table table = field.getDefiningMapping().getTable();
String schemaName = (table == null) ? null
: table.getSchema().getName();
DBIdentifier schemaName = (table == null) ? DBIdentifier.NULL
: table.getSchema().getIdentifier();
// if we have no join columns defined, there may be class-level join
// information with a more fully-qualified name for our table
String tableName = _tableName;
if (tableName != null && getColumns().isEmpty())
DBIdentifier tableName = _tableName;
if (!DBIdentifier.isNull(tableName) && getColumns().isEmpty())
tableName = field.getDefiningMapping().getMappingInfo().
getSecondaryTableName(tableName);
getSecondaryTableIdentifier(tableName);
return createTable(field, new TableDefaults() {
public String get(Schema schema) {
@ -145,13 +155,18 @@ public class FieldMappingInfo
return field.getMappingRepository().getMappingDefaults().
getTableName(field, schema);
}
public DBIdentifier getIdentifier(Schema schema) {
// TODO Auto-generated method stub
return field.getMappingRepository().getMappingDefaults().
getTableIdentifier(field, schema);
}
}, schemaName, tableName, adapt);
}
public ForeignKey getJoinForeignKey (final FieldMapping field, Table table,
boolean adapt) {
if (field.isUni1ToMFK()) {
List cols = field.getElementMapping().getValueInfo().getColumns();
List<Column> cols = field.getElementMapping().getValueInfo().getColumns();
return getJoin(field, table, adapt, cols);
}
return null;
@ -168,7 +183,7 @@ public class FieldMappingInfo
}
public ForeignKey getJoin(final FieldMapping field, Table table,
boolean adapt, List cols) {
boolean adapt, List<Column> cols) {
if (cols.isEmpty()) {
ClassMapping mapping;
if (field.isEmbedded() &&
@ -251,7 +266,7 @@ public class FieldMappingInfo
Column[] uniqueColumns = new Column[templateColumns.length];
Table table = getTable(field, true, adapt);
for (int i=0; i<uniqueColumns.length; i++) {
String columnName = templateColumns[i].getName();
DBIdentifier columnName = templateColumns[i].getIdentifier();
Column uniqueColumn = table.getColumn(columnName);
uniqueColumns[i] = uniqueColumn;
}
@ -302,12 +317,15 @@ public class FieldMappingInfo
Column tmplate = new Column();
// Compatibility option determines what should be used for
// the default order column name
boolean delimit = field.getMappingRepository().getDBDictionary().delimitAll();
if (field.getMappingRepository().getConfiguration()
.getCompatibilityInstance().getUseJPA2DefaultOrderColumnName()) {
// Use the same strategy as column to build the field name
tmplate.setName(field.getName() + "_ORDER");
} else {
tmplate.setName("ordr");
DBIdentifier sName = DBIdentifier.newColumn(field.getName(), delimit);
sName = DBIdentifier.append(sName,"_ORDER");
tmplate.setIdentifier(sName);
} else {
tmplate.setIdentifier(DBIdentifier.newColumn("ordr", delimit));
}
tmplate.setJavaType(JavaTypes.INT);
@ -337,7 +355,7 @@ public class FieldMappingInfo
if (field.getJoinForeignKey() != null)
_tableName = field.getMappingRepository().getDBDictionary().
getFullName(field.getTable(), true);
getFullIdentifier(field.getTable(), true);
ClassMapping def = field.getDefiningMapping();
setColumnIO(field.getJoinColumnIO());
@ -391,7 +409,7 @@ public class FieldMappingInfo
_joinTableUniques = new ArrayList<Unique>();
for (Unique unique:unqs) {
Unique copy = new Unique();
copy.setName(unique.getName());
copy.setIdentifier(unique.getIdentifier());
copy.setDeferred(unique.isDeferred());
_joinTableUniques.add(unique);
}
@ -399,13 +417,13 @@ public class FieldMappingInfo
public boolean hasSchemaComponents() {
return super.hasSchemaComponents() || _tableName != null
return super.hasSchemaComponents() || !DBIdentifier.isNull(_tableName)
|| _orderCol != null;
}
protected void clear(boolean canFlags) {
super.clear(canFlags);
_tableName = null;
_tableName = DBIdentifier.NULL;
_orderCol = null;
if (canFlags)
_canOrderCol = true;
@ -417,8 +435,8 @@ public class FieldMappingInfo
return;
FieldMappingInfo finfo = (FieldMappingInfo) info;
if (_tableName == null)
_tableName = finfo.getTableName();
if (DBIdentifier.isNull(_tableName))
_tableName = finfo.getTableIdentifier();
if (!_outer)
_outer = finfo.isJoinOuter();
if (_canOrderCol && _orderCol == null)

View File

@ -20,6 +20,7 @@ package org.apache.openjpa.jdbc.meta;
import java.util.Comparator;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.ColumnIO;
import org.apache.openjpa.jdbc.sql.Joins;
@ -30,6 +31,7 @@ import org.apache.openjpa.jdbc.sql.Select;
*
* @author Abe White
*/
@SuppressWarnings("serial")
class JDBCColumnOrder
implements JDBCOrder {
@ -64,15 +66,22 @@ class JDBCColumnOrder
_io = io;
}
/**
* @deprecated
*/
public String getName() {
return (_col == null) ? "" : _col.getName();
}
public DBIdentifier getIdentifier() {
return (_col == null) ? DBIdentifier.newColumn("") : _col.getIdentifier();
}
public boolean isAscending() {
return true;
}
public Comparator getComparator() {
public Comparator<?> getComparator() {
return null;
}

View File

@ -18,6 +18,7 @@
*/
package org.apache.openjpa.jdbc.meta;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.sql.Joins;
import org.apache.openjpa.jdbc.sql.Select;
import org.apache.openjpa.meta.Order;
@ -43,4 +44,7 @@ interface JDBCOrder
* we're selecting
*/
public void order(Select sel, ClassMapping elem, Joins joins);
public DBIdentifier getIdentifier();
}

View File

@ -20,6 +20,7 @@ package org.apache.openjpa.jdbc.meta;
import java.util.Comparator;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.sql.Joins;
import org.apache.openjpa.jdbc.sql.Select;
import org.apache.openjpa.lib.util.Localizer;
@ -30,6 +31,7 @@ import org.apache.openjpa.util.MetaDataException;
*
* @author Abe White
*/
@SuppressWarnings("serial")
class JDBCRelatedFieldOrder
implements JDBCOrder {
@ -49,15 +51,22 @@ class JDBCRelatedFieldOrder
_asc = asc;
}
/**
* @deprecated
*/
public String getName() {
return _fm.getName();
}
public DBIdentifier getIdentifier() {
return DBIdentifier.newColumn(_fm.getName());
}
public boolean isAscending() {
return _asc;
}
public Comparator getComparator() {
public Comparator<?> getComparator() {
return null;
}

View File

@ -20,6 +20,7 @@ package org.apache.openjpa.jdbc.meta;
import java.util.Comparator;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.sql.Joins;
import org.apache.openjpa.jdbc.sql.Select;
import org.apache.openjpa.meta.Order;
@ -30,11 +31,13 @@ import org.apache.openjpa.meta.Order;
*
* @author Abe White
*/
@SuppressWarnings("serial")
class JDBCValueOrder
implements JDBCOrder {
private final FieldMapping _fm;
private final boolean _asc;
private static final DBIdentifier SQL_ELEMENT = DBIdentifier.newColumn(Order.ELEMENT);
public JDBCValueOrder(FieldMapping fm, boolean asc) {
_fm = fm;
@ -45,11 +48,15 @@ class JDBCValueOrder
return Order.ELEMENT;
}
public DBIdentifier getIdentifier() {
return SQL_ELEMENT;
}
public boolean isAscending() {
return _asc;
}
public Comparator getComparator() {
public Comparator<?> getComparator() {
return null;
}

View File

@ -68,7 +68,7 @@ public class JavaSQLTypes
/**
* Return the proper date typecode.
*/
public static int getDateTypeCode(Class dtype) {
public static int getDateTypeCode(Class<?> dtype) {
if (dtype == java.util.Date.class)
return DATE;
if (dtype == java.sql.Date.class)

View File

@ -18,6 +18,7 @@
*/
package org.apache.openjpa.jdbc.meta;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.ForeignKey;
import org.apache.openjpa.jdbc.schema.Index;
@ -87,7 +88,7 @@ public interface MappingDefaults {
* @param adapt whether we can adapt the mapping or schema
* @return the handler/strategy alias or instance, or null
*/
public Object getStrategy(ValueMapping vm, Class type, boolean adapt);
public Object getStrategy(ValueMapping vm, Class<?> type, boolean adapt);
/**
* Return the default discriminator value for the given instance.
@ -97,15 +98,30 @@ public interface MappingDefaults {
/**
* Return the default table name for the given class. This method is
* only called for classes mapped to their own table.
* @deprecated
*/
public String getTableName(ClassMapping cls, Schema defaultSchema);
/**
* Return the default table name for the given class. This method is
* only called for classes mapped to their own table.
*/
public DBIdentifier getTableIdentifier(ClassMapping cls, Schema defaultSchema);
/**
* Return the default secondary table name for the given field. This
* method is only called for fields whose strategy requires a secondary
* table.
* @deprecated
*/
public String getTableName(FieldMapping fm, Schema defaultSchema);
/**
* Return the default secondary table name for the given field. This
* method is only called for fields whose strategy requires a secondary
* table.
*/
public String getTableName(FieldMapping fm, Schema defaultSchema);
public DBIdentifier getTableIdentifier(FieldMapping fm, Schema defaultSchema);
/**
* Fill in default information for the given datastore identity columns.
@ -170,21 +186,50 @@ public interface MappingDefaults {
* @param inverse whether this is an inverse foreign key
* @param pos the index of this column in the logical foreign key
* @param cols the number of columns in the logical foreign key
* @deprecated
*/
public void populateForeignKeyColumn(ValueMapping vm, String name,
Table local, Table foreign, Column col, Object target, boolean inverse,
int pos, int cols);
/**
* Fill in default information for the given column used to join a value
* to its related type. The column will be a clone of the target
* column, or have its name and Java type set in the case of a constant
* target.
*
* @param name base name for value, as decided by mapping
* @param target the target of this column in the join; may be
* another column or a constant value
* @param inverse whether this is an inverse foreign key
* @param pos the index of this column in the logical foreign key
* @param cols the number of columns in the logical foreign key
*/
public void populateForeignKeyColumn(ValueMapping vm, DBIdentifier name,
Table local, Table foreign, Column col, Object target, boolean inverse,
int pos, int cols);
/**
* Fill in default information for the given value columns.
* The columns' name and Java type will already be populated with generic
* defaults that may be replaced.
*
* @param name base name for value, as decided by mapping
* @deprecated
*/
public void populateColumns(ValueMapping vm, String name, Table table,
Column[] cols);
/**
* Fill in default information for the given value columns.
* The columns' name and Java type will already be populated with generic
* defaults that may be replaced.
*
* @param name base name for value, as decided by mapping
*/
public void populateColumns(ValueMapping vm, DBIdentifier name, Table table,
Column[] cols);
/**
* Fill in default information for the given order columns.
* The columns' name and Java type will already be populated with generic
@ -206,10 +251,24 @@ public interface MappingDefaults {
* @return false if the given value should not have null indicator
* columns by default; fill in default information even
* when returning false in case the user forces an indicator
* @deprecated
*/
public boolean populateNullIndicatorColumns(ValueMapping vm, String name,
Table table, Column[] cols);
/**
* Fill in default information for the given null indicator columns.
* The columns' name and Java type will already be populated with generic
* defaults that may be replaced.
*
* @param name base name for value, as decided by mapping
* @return false if the given value should not have null indicator
* columns by default; fill in default information even
* when returning false in case the user forces an indicator
*/
public boolean populateNullIndicatorColumns(ValueMapping vm, DBIdentifier name,
Table table, Column[] cols);
/**
* Return a default foreign key for the join from this class' table to its
* superclass' table, or null for a logical foreign key only. Do not
@ -236,10 +295,23 @@ public interface MappingDefaults {
*
* @param name base name for value, as decided by mapping
* @param inverse whether this is an inverse key
* @deprecated
*/
public ForeignKey getForeignKey(ValueMapping vm, String name, Table local,
Table foreign, boolean inverse);
/**
* Return a default foreign key for the join from this value to its
* related type, or null for a logical foreign key only. Do not
* add columns to the key or add the key to the table; only fill in
* its information such as name, delete action, etc.
*
* @param name base name for value, as decided by mapping
* @param inverse whether this is an inverse key
*/
public ForeignKey getForeignKey(ValueMapping vm, DBIdentifier name, Table local,
Table foreign, boolean inverse);
/**
* Return a default index for the join, or null if the
* join columns should not be indexed by default. Do not
@ -255,10 +327,22 @@ public interface MappingDefaults {
* uniqueness, etc.
*
* @param name base name for value, as decided by mapping
* @deprecated
*/
public Index getIndex(ValueMapping vm, String name, Table table,
Column[] cols);
/**
* Return a default index for the value, or null if the value columns
* should not be indexed by default. Do not add columns to the index or
* add the index to the table; only fill in its information such as name,
* uniqueness, etc.
*
* @param name base name for value, as decided by mapping
*/
public Index getIndex(ValueMapping vm, DBIdentifier name, Table table,
Column[] cols);
/**
* Return a default index for the version, or null if the
* version columns should not be indexed by default. Do not
@ -290,15 +374,34 @@ public interface MappingDefaults {
* information such as name, deferrability, etc.
*
* @param name base name for value, as decided by mapping
* @deprecated
*/
public Unique getUnique(ValueMapping vm, String name, Table table,
Column[] cols);
/**
* Return a default constraint for the value, or null if the value columns
* should not be constrained by default. Do not add columns to the
* constraint or add the constraint to the table; only fill in its
* information such as name, deferrability, etc.
*
* @param name base name for value, as decided by mapping
*/
public Unique getUnique(ValueMapping vm, DBIdentifier name, Table table,
Column[] cols);
/**
* Return the name of the primary key for the table of the given class,
* or null for database default.
* @deprecated
*/
public String getPrimaryKeyName(ClassMapping cm, Table table);
/**
* Return the name of the primary key for the table of the given class,
* or null for database default.
*/
public String getPrimaryKeyName(ClassMapping cm, Table table);
public DBIdentifier getPrimaryKeyIdentifier(ClassMapping cm, Table table);
/**
* If desired, install a primary key on the given secondary table.

View File

@ -24,6 +24,8 @@ import java.util.Map;
import java.util.Properties;
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
import org.apache.openjpa.jdbc.identifier.Normalizer;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.meta.strats.UntypedPCValueHandler;
import org.apache.openjpa.jdbc.meta.strats.EnumValueHandler;
import org.apache.openjpa.jdbc.schema.Column;
@ -36,7 +38,8 @@ import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.lib.conf.Configurable;
import org.apache.openjpa.lib.conf.Configuration;
import org.apache.openjpa.lib.conf.Configurations;
import org.apache.openjpa.lib.util.JavaVersions;
import org.apache.openjpa.lib.identifier.Identifier;
import org.apache.openjpa.lib.identifier.IdentifierUtil;
import org.apache.openjpa.meta.JavaTypes;
import serp.util.Strings;
@ -66,11 +69,11 @@ public class MappingDefaultsImpl
private boolean _addNullInd = false;
private boolean _ordinalEnum = false;
private boolean _stringifyUnmapped = false;
private String _dsIdName = null;
private String _versName = null;
private String _discName = null;
private String _orderName = null;
private String _nullIndName = null;
private DBIdentifier _dsIdName = DBIdentifier.NULL;
private DBIdentifier _versName = DBIdentifier.NULL;
private DBIdentifier _discName = DBIdentifier.NULL;
private DBIdentifier _orderName = DBIdentifier.NULL;
private DBIdentifier _nullIndName = DBIdentifier.NULL;
private boolean _removeHungarianNotation = false;
public boolean isRemoveHungarianNotation() {
@ -333,83 +336,133 @@ public class MappingDefaultsImpl
/**
* Default base name for datastore identity columns, or null to the
* mapping's built-in name.
* @deprecated
*/
public String getDataStoreIdColumnName() {
return _dsIdName;
return getDataStoreIdColumnIdentifier().getName();
}
public DBIdentifier getDataStoreIdColumnIdentifier() {
return _dsIdName == null ? DBIdentifier.NULL : _dsIdName;
}
/**
* Default base name for datastore identity columns, or null to the
* mapping's built-in name.
* @deprecated
*/
public void setDataStoreIdColumnName(String dsIdName) {
setDataStoreIdColumnIdentifier(DBIdentifier.newColumn(dsIdName));
}
public void setDataStoreIdColumnIdentifier(DBIdentifier dsIdName) {
_dsIdName = dsIdName;
}
/**
* Default base name for version identity columns, or null to the mapping's
* built-in name.
* @deprecated
*/
public String getVersionColumnName() {
return _versName;
return getVersionColumnIdentifier().getName();
}
public DBIdentifier getVersionColumnIdentifier() {
return _versName == null ? DBIdentifier.NULL : _versName;
}
/**
* Default base name for version identity columns, or null to the mapping's
* built-in name.
* @deprecated
*/
public void setVersionColumnName(String versName) {
setVersionColumnIdentifier(DBIdentifier.newColumn(versName));
}
public void setVersionColumnIdentifier(DBIdentifier versName) {
_versName = versName;
}
/**
* Default base name for discriminator columns, or null to the mapping's
* built-in name.
* @deprecated
*/
public String getDiscriminatorColumnName() {
return _discName;
return getDiscriminatorColumnIdentifier().getName();
}
public DBIdentifier getDiscriminatorColumnIdentifier() {
return _discName == null ? DBIdentifier.NULL : _discName;
}
/**
* Default base name for discriminator columns, or null to the mapping's
* built-in name.
* @deprecated
*/
public void setDiscriminatorColumnName(String discName) {
setDiscriminatorColumnIdentifier(DBIdentifier.newColumn(discName));
}
public void setDiscriminatorColumnIdentifier(DBIdentifier discName) {
_discName = discName;
}
/**
* Default base name for order columns, or null to the mapping's
* built-in name.
* @deprecated
*/
public String getOrderColumnName() {
return _orderName;
return getOrderColumnIdentifier().getName();
}
public DBIdentifier getOrderColumnIdentifier() {
return _orderName == null ? DBIdentifier.NULL : _orderName;
}
/**
* Default base name for order columns, or null to the mapping's
* built-in name.
* @deprecated
*/
public void setOrderColumnName(String orderName) {
setOrderColumnIdentifier(DBIdentifier.newColumn(orderName));
}
public void setOrderColumnIdentifier(DBIdentifier orderName) {
_orderName = orderName;
}
/**
* Default base name for null indicator columns, or null to the mapping's
* built-in name.
* @deprecated
*/
public String getNullIndicatorColumnName() {
return _nullIndName;
return getNullIndicatorColumnIdentifier().getName();
}
public DBIdentifier getNullIndicatorColumnIdentifier() {
return _nullIndName == null ? DBIdentifier.NULL : _nullIndName;
}
/**
* Default base name for null indicator columns, or null to the mapping's
* built-in name.
* @deprecated
*/
public void setNullIndicatorColumnName(String nullIndName) {
setNullIndicatorColumnIdentifier(DBIdentifier.newColumn(nullIndName));
}
public void setNullIndicatorColumnIdentifier(DBIdentifier nullIndName) {
_nullIndName = nullIndName;
}
public boolean defaultMissingInfo() {
return _defMissing;
}
@ -451,7 +504,7 @@ public class MappingDefaultsImpl
return null;
}
public Object getStrategy(ValueMapping vm, Class type, boolean adapt) {
public Object getStrategy(ValueMapping vm, Class<?> type, boolean adapt) {
Object ret = _fieldMap.get(type.getName());
if (ret != null)
return ret;
@ -511,33 +564,39 @@ public class MappingDefaultsImpl
public String getTableName(ClassMapping cls, Schema schema) {
String name = Strings.getClassName(cls.getDescribedType()).
replace('$', '_');
replace(IdentifierUtil.DOLLAR_CHAR, IdentifierUtil.UNDERSCORE_CHAR);
if (!_defMissing)
name = dict.getValidTableName(name, schema);
return name;
}
public DBIdentifier getTableIdentifier(ClassMapping cls, Schema schema) {
return DBIdentifier.newTable(getTableName(cls, schema));
}
public String getTableName(FieldMapping fm, Schema schema) {
String name = fm.getName();
return getTableIdentifier(fm, schema).getName();
}
public DBIdentifier getTableIdentifier(FieldMapping fm, Schema schema) {
DBIdentifier sName = DBIdentifier.newTable(fm.getName());
Table table = fm.getDefiningMapping().getTable();
if (table != null) {
String tableName = table.getName();
if (tableName.length() > 5)
tableName = tableName.substring(0, 5);
name = tableName + "_" + name;
DBIdentifier tableName = DBIdentifier.truncate(table.getIdentifier(),5);
sName = DBIdentifier.append(tableName, fm.getName());
}
if (!_defMissing)
name = dict.getValidTableName(name, schema);
return name;
sName = dict.getValidTableName(sName, schema);
return sName;
}
public void populateDataStoreIdColumns(ClassMapping cls, Table table,
Column[] cols) {
for (int i = 0; i < cols.length; i++) {
if (_dsIdName != null && cols.length == 1)
cols[i].setName(_dsIdName);
else if (_dsIdName != null)
cols[i].setName(_dsIdName + i);
if (!DBIdentifier.isNull(_dsIdName) && cols.length == 1)
cols[i].setIdentifier(_dsIdName);
else if (!DBIdentifier.isNull(_dsIdName))
cols[i].setIdentifier(DBIdentifier.append(_dsIdName, Integer.toString(i)));
correctName(table, cols[i]);
}
}
@ -548,41 +607,31 @@ public class MappingDefaultsImpl
protected void correctName(Table table, Column col) {
if (!_defMissing || _removeHungarianNotation)
{
String name = col.getName();
DBIdentifier name = col.getIdentifier();
if (_removeHungarianNotation)
name = removeHungarianNotation(name);
String correctedName = dict.getValidColumnName(name, table);
col.setName(correctedName);
name = DBIdentifier.removeHungarianNotation(name);
DBIdentifier correctedName = dict.getValidColumnName(name, table);
col.setIdentifier(correctedName);
table.addCorrectedColumnName(correctedName, true);
}
}
protected String removeHungarianNotation(String columnName) {
char[] name = columnName.toCharArray();
int newStart = 0;
for (int i = 0; i < name.length; i++) {
if (Character.isUpperCase(name[i]))
{
newStart = i;
break;
}
}
return columnName.substring(newStart);
return Normalizer.removeHungarianNotation(columnName);
}
public void populateColumns(Version vers, Table table, Column[] cols) {
for (int i = 0; i < cols.length; i++) {
if (_versName != null && cols.length == 1)
cols[i].setName(_versName);
else if (_versName != null) {
if (i == 0)
cols[i].setName(_versName);
else
cols[i].setName(_versName + "_" + i);
} else if (_versName != null)
cols[i].setName(_versName + i);
if (!DBIdentifier.isNull(_versName) && cols.length == 1)
cols[i].setIdentifier(_versName);
else if (!DBIdentifier.isNull(_versName)) {
if (i == 0) {
cols[i].setIdentifier(_versName);
} else {
cols[i].setIdentifier(DBIdentifier.append(_versName, Integer.toString(i)));
}
} else if (!DBIdentifier.isNull(_versName))
cols[i].setIdentifier(DBIdentifier.append(_versName, Integer.toString(i)));
correctName(table, cols[i]);
}
}
@ -590,10 +639,10 @@ public class MappingDefaultsImpl
public void populateColumns(Discriminator disc, Table table,
Column[] cols) {
for (int i = 0; i < cols.length; i++) {
if (_discName != null && cols.length == 1)
cols[i].setName(_discName);
else if (_discName != null)
cols[i].setName(_discName + i);
if (!DBIdentifier.isNull(_discName) && cols.length == 1)
cols[i].setIdentifier(_discName);
else if (!DBIdentifier.isNull(_discName))
cols[i].setIdentifier(DBIdentifier.append(_discName, Integer.toString(i)));
correctName(table, cols[i]);
}
}
@ -608,17 +657,32 @@ public class MappingDefaultsImpl
correctName(local, col);
}
/**
* @deprecated
*/
public void populateForeignKeyColumn(ValueMapping vm, String name,
Table local, Table foreign, Column col, Object target, boolean inverse,
int pos, int cols) {
populateForeignKeyColumn(vm, DBIdentifier.newColumn(name), local, foreign, col,
target, inverse, pos, cols);
}
public void populateForeignKeyColumn(ValueMapping vm, DBIdentifier name,
Table local, Table foreign, Column col, Object target, boolean inverse,
int pos, int cols) {
if (cols == 1)
col.setName(name);
col.setIdentifier(name);
else if (target instanceof Column)
col.setName(name + "_" + ((Column) target).getName());
col.setIdentifier(DBIdentifier.combine(name,((Column) target).getIdentifier().getName()));
correctName(local, col);
}
public void populateColumns(ValueMapping vm, String name, Table table,
Column[] cols) {
populateColumns(vm, DBIdentifier.newColumn(name), table, cols);
}
public void populateColumns(ValueMapping vm, DBIdentifier name, Table table,
Column[] cols) {
for (int i = 0; i < cols.length; i++)
correctName(table, cols[i]);
@ -627,23 +691,31 @@ public class MappingDefaultsImpl
public boolean populateOrderColumns(FieldMapping fm, Table table,
Column[] cols) {
for (int i = 0; i < cols.length; i++) {
if (_orderName != null && cols.length == 1)
cols[i].setName(_orderName);
else if (_orderName != null)
cols[i].setName(_orderName + i);
if (!DBIdentifier.isNull(_orderName) && cols.length == 1)
cols[i].setIdentifier(_orderName);
else if (!DBIdentifier.isNull(_orderName))
cols[i].setIdentifier(DBIdentifier.append(_orderName, Integer.toString(i)));
correctName(table, cols[i]);
}
return _orderLists && (JavaTypes.ARRAY == fm.getTypeCode()
|| List.class.isAssignableFrom(fm.getType()));
}
/**
* @deprecated
*/
public boolean populateNullIndicatorColumns(ValueMapping vm, String name,
Table table, Column[] cols) {
return populateNullIndicatorColumns(vm, DBIdentifier.newColumn(name), table, cols);
}
public boolean populateNullIndicatorColumns(ValueMapping vm, DBIdentifier name,
Table table, Column[] cols) {
for (int i = 0; i < cols.length; i++) {
if (_nullIndName != null && cols.length == 1)
cols[i].setName(_nullIndName);
else if (_nullIndName != null)
cols[i].setName(_nullIndName + i);
if (!DBIdentifier.isNull(_nullIndName) && cols.length == 1)
cols[i].setIdentifier(_nullIndName);
else if (!DBIdentifier.isNull(_nullIndName))
cols[i].setIdentifier(DBIdentifier.append(_nullIndName, Integer.toString(i)));
correctName(table, cols[i]);
}
return _addNullInd;
@ -669,7 +741,15 @@ public class MappingDefaultsImpl
return fk;
}
/**
* @deprecated
*/
public ForeignKey getForeignKey(ValueMapping vm, String name, Table local,
Table foreign, boolean inverse) {
return getForeignKey(vm, DBIdentifier.newForeignKey(name), local, foreign, inverse);
}
public ForeignKey getForeignKey(ValueMapping vm, DBIdentifier name, Table local,
Table foreign, boolean inverse) {
if (_fkAction == ForeignKey.ACTION_NONE)
return null;
@ -687,7 +767,7 @@ public class MappingDefaultsImpl
return null;
Index idx = new Index();
idx.setName(getIndexName(null, table, cols));
idx.setIdentifier(getIndexName(DBIdentifier.NULL, table, cols));
return idx;
}
@ -703,20 +783,34 @@ public class MappingDefaultsImpl
/**
* Generate an index name.
* @deprecated
*/
protected String getIndexName(String name, Table table, Column[] cols) {
// always use dict for index names because no spec mandates them
// based on defaults
if (name == null)
name = cols[0].getName();
if (_removeHungarianNotation)
name = removeHungarianNotation(name);
return dict.getValidIndexName(name, table);
return getIndexName(DBIdentifier.newIndex(name), table, cols).getName();
}
protected DBIdentifier getIndexName(DBIdentifier name, Table table, Column[] cols) {
// always use dict for index names because no spec mandates them
// based on defaults
DBIdentifier sName = name;
if (DBIdentifier.isNull(sName))
sName = cols[0].getIdentifier();
if (_removeHungarianNotation)
sName = DBIdentifier.removeHungarianNotation(sName);
return dict.getValidIndexName(sName, table);
}
/**
* @deprecated
*/
public Index getIndex(ValueMapping vm, String name, Table table,
Column[] cols) {
return getIndex(vm, DBIdentifier.newIndex(name), table, cols);
}
public Index getIndex(ValueMapping vm, DBIdentifier name, Table table,
Column[] cols) {
if (!_indexFK || vm.getForeignKey() == null
|| !vm.getForeignKey().isLogical())
@ -725,7 +819,7 @@ public class MappingDefaultsImpl
return null;
Index idx = new Index();
idx.setName(getIndexName(name, table, cols));
idx.setIdentifier(getIndexName(name, table, cols));
return idx;
}
@ -733,7 +827,7 @@ public class MappingDefaultsImpl
if (!_indexVers)
return null;
Index idx = new Index();
idx.setName(getIndexName(_versName, table, cols));
idx.setIdentifier(getIndexName(_versName, table, cols));
return idx;
}
@ -741,7 +835,7 @@ public class MappingDefaultsImpl
if (!_indexDisc)
return null;
Index idx = new Index();
idx.setName(getIndexName(_discName, table, cols));
idx.setIdentifier(getIndexName(_discName, table, cols));
return idx;
}
@ -749,15 +843,30 @@ public class MappingDefaultsImpl
return null;
}
/**
* @deprecated
*/
public Unique getUnique(ValueMapping vm, String name, Table table,
Column[] cols) {
return null;
}
public Unique getUnique(ValueMapping vm, DBIdentifier name, Table table,
Column[] cols) {
return null;
}
/**
* @deprecated
*/
public String getPrimaryKeyName(ClassMapping cm, Table table) {
return null;
}
public DBIdentifier getPrimaryKeyIdentifier(ClassMapping cm, Table table) {
return DBIdentifier.NULL;
}
public void installPrimaryKey(FieldMapping fm, Table table) {
}

View File

@ -26,6 +26,9 @@ import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
import org.apache.openjpa.jdbc.identifier.Normalizer;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.identifier.QualifiedDBIdentifier;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.ColumnIO;
import org.apache.openjpa.jdbc.schema.ForeignKey;
@ -51,6 +54,7 @@ import serp.util.Strings;
*
* @author Abe White
*/
@SuppressWarnings("serial")
public abstract class MappingInfo
implements Serializable {
@ -64,7 +68,7 @@ public abstract class MappingInfo
(MappingInfo.class);
private String _strategy = null;
private List _cols = null;
private List<Column> _cols = null;
private Index _idx = null;
private Unique _unq = null;
private ForeignKey _fk = null;
@ -92,19 +96,30 @@ public abstract class MappingInfo
/**
* Raw column data.
*/
public List getColumns() {
return (_cols == null) ? Collections.EMPTY_LIST : _cols;
public List<Column> getColumns() {
if (_cols == null) {
return Collections.emptyList();
}
return _cols;
}
/**
* Gets the columns whose table name matches the given table name.
* @deprecated
*/
public List getColumns(String tableName) {
public List<Column> getColumns(String tableName) {
return getColumns(DBIdentifier.newTable(tableName));
}
/**
* Gets the columns whose table name matches the given table name.
*/
public List<Column> getColumns(DBIdentifier tableName) {
if (_cols == null)
return Collections.EMPTY_LIST;
List result = new ArrayList();
for (Object col : _cols) {
if (StringUtils.equals(((Column)col).getTableName(),
return Collections.emptyList();
List<Column> result = new ArrayList<Column>();
for (Column col : _cols) {
if (DBIdentifier.equal(col.getTableIdentifier(),
tableName))
result.add(col);
}
@ -114,7 +129,7 @@ public abstract class MappingInfo
/**
* Raw column data.
*/
public void setColumns(List cols) {
public void setColumns(List<Column> cols) {
_cols = cols;
}
@ -321,12 +336,12 @@ public abstract class MappingInfo
_canFK = info.canForeignKey();
}
_implicitRelation = info.isImplicitRelation();
List cols = getColumns();
List icols = info.getColumns();
List<Column> cols = getColumns();
List<Column> icols = info.getColumns();
if (!icols.isEmpty() && (cols.isEmpty()
|| cols.size() == icols.size())) {
if (cols.isEmpty())
cols = new ArrayList(icols.size());
cols = new ArrayList<Column>(icols.size());
for (int i = 0; i < icols.size(); i++) {
if (cols.size() == i)
cols.add(new Column());
@ -448,7 +463,7 @@ public abstract class MappingInfo
Column col;
for (int i = 0; !join && i < _cols.size(); i++) {
col = (Column) _cols.get(i);
if (col.getTarget() != null)
if (!DBIdentifier.isNull(col.getTargetIdentifier()))
join = true;
}
}
@ -469,43 +484,48 @@ public abstract class MappingInfo
* @param schemaName default schema if known, or null
* @param given given table name
* @param adapt whether we can alter the schema or mappings
* @deprecated
*/
public Table createTable(MetaDataContext context, TableDefaults def,
String schemaName, String given, boolean adapt) {
return createTable(context, def, DBIdentifier.newSchema(schemaName),
DBIdentifier.newTable(given), adapt);
}
public Table createTable(MetaDataContext context, TableDefaults def,
DBIdentifier schemaName, DBIdentifier given, boolean adapt) {
MappingRepository repos = (MappingRepository) context.getRepository();
if (given == null && (def == null || (!adapt
if (DBIdentifier.isNull(given) && (def == null || (!adapt
&& !repos.getMappingDefaults().defaultMissingInfo())))
throw new MetaDataException(_loc.get("no-table", context));
if (schemaName == null)
schemaName = Schemas.getNewTableSchema((JDBCConfiguration)
if (DBIdentifier.isNull(schemaName))
schemaName = Schemas.getNewTableSchemaIdentifier((JDBCConfiguration)
repos.getConfiguration());
// if no given and adapting or defaulting missing info, use template
SchemaGroup group = repos.getSchemaGroup();
Schema schema = null;
if (given == null) {
if (DBIdentifier.isNull(given)) {
schema = group.getSchema(schemaName);
if (schema == null)
schema = group.addSchema(schemaName);
given = def.get(schema);
given = def.getIdentifier(schema);
}
String fullName;
String sep = repos.getDBDictionary().catalogSeparator;
int dotIdx = given.lastIndexOf(sep);
if (dotIdx == -1)
fullName = (schemaName == null) ? given : schemaName + sep + given;
else {
fullName = given;
QualifiedDBIdentifier path = QualifiedDBIdentifier.getPath(given);
if (DBIdentifier.isNull(path.getSchemaName())) {
if (!DBIdentifier.isNull(schemaName)) {
path.setSchemaName(schemaName);
}
} else {
schemaName = path.getSchemaName();
schema = null;
schemaName = given.substring(0, dotIdx);
given = given.substring(dotIdx + 1);
}
// look for named table using full name and findTable, which allows
// the dynamic schema factory to create the table if needed
Table table = group.findTable(fullName);
Table table = group.findTable(path);
if (table != null)
return table;
if (!adapt)
@ -543,7 +563,7 @@ public abstract class MappingInfo
// mapping, or none at all if we're adapting. can't just given one of
// n columns because we don't know which of the n columns the info
// applies to
List given = getColumns();
List<Column> given = getColumns();
if (context instanceof FieldMapping && ((FieldMapping)context).hasMapsIdCols())
given = ((FieldMapping)context).getValueInfo().getMapsIdColumns();
@ -553,7 +573,7 @@ public abstract class MappingInfo
if ((!given.isEmpty() || (!adapt && !fill))
&& given.size() != tmplates.length) {
// also consider when this info has columns from multiple tables
given = getColumns(table.getName());
given = getColumns(table.getIdentifier());
if ((!adapt && !fill) && given.size() != tmplates.length) {
// try default table
given = getColumns("");
@ -577,7 +597,7 @@ public abstract class MappingInfo
return cols;
}
boolean canMerge(List given, Column[] templates, boolean adapt,
boolean canMerge(List<Column> given, Column[] templates, boolean adapt,
boolean fill) {
return !((!given.isEmpty() || (!adapt && !fill))
&& given.size() != templates.length);
@ -627,8 +647,8 @@ public abstract class MappingInfo
assertTable(context, table);
// if not adapting must provide column name at a minimum
String colName = (given == null) ? null : given.getName();
if (colName == null && !adapt && !fill)
DBIdentifier colName = (given == null) ? DBIdentifier.NULL : given.getIdentifier();
if (DBIdentifier.isNull(colName) && !adapt && !fill)
throw new MetaDataException(_loc.get(prefix + "-no-col-name",
context));
@ -638,15 +658,15 @@ public abstract class MappingInfo
// determine the column name based on given info, or template if none;
// also make sure that if the user gave a column name, he didn't try
// to put the column in an unexpected table
if (colName == null)
colName = tmplate.getName();
int dotIdx = colName.lastIndexOf(dict.catalogSeparator);
if (dotIdx == 0)
colName = colName.substring(1);
else if (dotIdx != -1) {
findTable(context, colName.substring(0, dotIdx), table,
if (DBIdentifier.isNull(colName))
colName = tmplate.getIdentifier();
QualifiedDBIdentifier path = QualifiedDBIdentifier.getPath(colName);
if (path.isUnqualifiedColumn()) {
colName = path.getIdentifier();
} else if (!DBIdentifier.isNull(path.getObjectTableName())) {
findTable(context, path.getObjectTableName(), table,
null, null);
colName = colName.substring(dotIdx + 1);
colName = path.getUnqualifiedName();
}
// find existing column
@ -658,8 +678,8 @@ public abstract class MappingInfo
// should seldom if ever occur as long as the database dictionaries
// are kept up-to-date.
//
if ((colName.length() > dict.maxColumnNameLength) ||
dict.getInvalidColumnWordSet().contains(colName.toUpperCase()) &&
if ((colName.getName().length() > dict.maxColumnNameLength) ||
dict.getInvalidColumnWordSet().contains(DBIdentifier.toUpper(colName).getName()) &&
!(table.getClass().getName().contains("DynamicTable"))) {
colName=dict.getValidColumnName(colName, new Table());
col = table.getColumn(colName);
@ -814,7 +834,7 @@ public abstract class MappingInfo
* @param rel if we're finding the target table of a join, the
* joined-to type; allows us to also look in its superclass tables
*/
private static Table findTable(MetaDataContext context, String name,
private static Table findTable(MetaDataContext context, DBIdentifier name,
Table expected, Table inverse, ClassMapping rel) {
// is this the expected table?
if (expected == null && rel != null)
@ -837,15 +857,15 @@ public abstract class MappingInfo
// none of the possible tables
throw new MetaDataException(_loc.get("col-wrong-table", context,
expected, name));
expected, name.getName()));
}
/**
* Return whether the given name matches the given table.
*/
private static boolean isTableName(String name, Table table) {
return name.equalsIgnoreCase(table.getName())
|| name.equalsIgnoreCase(table.getFullName());
private static boolean isTableName(DBIdentifier name, Table table) {
return DBIdentifier.equal(name, table.getIdentifier())
|| DBIdentifier.equal(name, table.getFullIdentifier());
}
/**
@ -910,10 +930,10 @@ public abstract class MappingInfo
if (_idx == null && (tmplate == null || (!adapt && !fill)))
return null;
String name = null;
DBIdentifier name = DBIdentifier.NULL;
boolean unq;
if (_idx != null) {
name = _idx.getName();
name = _idx.getIdentifier();
unq = _idx.isUnique();
// preserve multiple columns if they are specified in the index
if (_idx.getColumns() != null && _idx.getColumns().length > 1)
@ -922,11 +942,11 @@ public abstract class MappingInfo
unq = tmplate.isUnique();
// if no name provided by user info, make one
if (name == null) {
if (DBIdentifier.isNull(name)) {
if (tmplate != null)
name = tmplate.getName();
name = tmplate.getIdentifier();
else {
name = cols[0].getName();
name = cols[0].getIdentifier();
name = repos.getDBDictionary().getValidIndexName(name, table);
}
}
@ -1009,13 +1029,13 @@ public abstract class MappingInfo
if (!adapt && !fill && _unq == null)
return null;
String name;
DBIdentifier name = DBIdentifier.NULL;
boolean deferred;
if (_unq != null) {
name = _unq.getName();
name = _unq.getIdentifier();
deferred = _unq.isDeferred();
} else {
name = tmplate.getName();
name = tmplate.getIdentifier();
deferred = tmplate.isDeferred();
}
@ -1027,8 +1047,8 @@ public abstract class MappingInfo
deferred = false;
}
if (StringUtils.isEmpty(name)) {
name = cols[0].getName();
if (DBIdentifier.isEmpty(name)) {
name = cols[0].getIdentifier();
name = repos.getDBDictionary().getValidUniqueName(name, table);
}
@ -1054,7 +1074,7 @@ public abstract class MappingInfo
* @param adapt whether we can modify the existing mapping or schema
*/
protected ForeignKey createForeignKey(MetaDataContext context,
String prefix, List given, ForeignKeyDefaults def, Table table,
String prefix, List<Column> given, ForeignKeyDefaults def, Table table,
ClassMapping cls, ClassMapping rel, boolean inversable, boolean adapt) {
assertTable(context, table);
if (prefix == null)
@ -1116,10 +1136,10 @@ public abstract class MappingInfo
if (exist != null) {
// make existing key logical?
if (!_canFK) {
if (exist.getDeleteAction() != exist.ACTION_NONE && !adapt)
if (exist.getDeleteAction() != ForeignKey.ACTION_NONE && !adapt)
throw new MetaDataException(_loc.get(prefix
+ "-fk-exists", context));
exist.setDeleteAction(exist.ACTION_NONE);
exist.setDeleteAction(ForeignKey.ACTION_NONE);
}
if (_fk != null && _fk.isDeferred() && !exist.isDeferred()) {
@ -1140,7 +1160,7 @@ public abstract class MappingInfo
return exist;
}
String name = null;
DBIdentifier name = DBIdentifier.NULL;
int delAction = ForeignKey.ACTION_NONE;
int upAction = ForeignKey.ACTION_NONE;
boolean deferred = false;
@ -1149,22 +1169,22 @@ public abstract class MappingInfo
: def.get(local, foreign, _join == JOIN_INVERSE);
if (_fk != null && (tmplate == null || (!adapt && !fill))) {
// if not adapting or no template info use given data
name = _fk.getName();
name = _fk.getIdentifier();
delAction = _fk.getDeleteAction();
upAction = _fk.getUpdateAction();
deferred = _fk.isDeferred();
} else if (_canFK && (adapt || fill)) {
if (_fk == null && tmplate != null) {
// no user given info; use template data
name = tmplate.getName();
name = tmplate.getIdentifier();
delAction = tmplate.getDeleteAction();
upAction = tmplate.getUpdateAction();
deferred = tmplate.isDeferred();
} else if (_fk != null && tmplate != null) {
// merge user and template data, always letting user info win
name = _fk.getName();
if (name == null && tmplate.getName() != null)
name = tmplate.getName();
name = _fk.getIdentifier();
if (DBIdentifier.isNull(name) && !DBIdentifier.isNull(tmplate.getIdentifier()))
name = tmplate.getIdentifier();
delAction = _fk.getDeleteAction();
if (delAction == ForeignKey.ACTION_NONE)
delAction = tmplate.getDeleteAction();
@ -1216,7 +1236,7 @@ public abstract class MappingInfo
* Use the join information to populate our internal column I/O data.
*/
private void setIOFromJoins(ForeignKey fk, Object[][] joins) {
List cols = getColumns();
List<Column> cols = getColumns();
_io = null;
if (cols.isEmpty())
return;
@ -1255,7 +1275,7 @@ public abstract class MappingInfo
*/
private Object[][] createJoins(MetaDataContext context,
String prefix, Table table, ClassMapping cls, ClassMapping rel,
List given, ForeignKeyDefaults def, boolean inversable, boolean adapt) {
List<Column> given, ForeignKeyDefaults def, boolean inversable, boolean adapt) {
MappingRepository repos = (MappingRepository) context.getRepository();
boolean fill = repos.getMappingDefaults().defaultMissingInfo();
Object[][] joins;
@ -1271,7 +1291,7 @@ public abstract class MappingInfo
Column tmplate;
for (int i = 0; i < targets.length; i++) {
tmplate = new Column();
tmplate.setName(targets[i].getName());
tmplate.setIdentifier(targets[i].getIdentifier());
tmplate.setJavaType(targets[i].getJavaType());
tmplate.setType(targets[i].getType());
tmplate.setTypeName(targets[i].getTypeName());
@ -1328,16 +1348,16 @@ public abstract class MappingInfo
ClassMapping rel, ForeignKeyDefaults def, boolean inversable,
boolean adapt, boolean fill) {
// default to the primary key column name if this is a pk join
String name = given.getName();
if (name == null && given != null
DBIdentifier name = given.getIdentifier();
if (DBIdentifier.isNull(name) && given != null
&& given.getFlag(Column.FLAG_PK_JOIN) && cls != null) {
Column[] pks = cls.getPrimaryKeyColumns();
if (pks.length == 1)
name = pks[0].getName();
name = pks[0].getIdentifier();
}
// if we can't adapt, then the user must at least give a column name
if (name == null && !adapt && !fill)
if (DBIdentifier.isNull(name) && !adapt && !fill)
throw new MetaDataException(_loc.get(prefix + "-no-fkcol-name",
context));
@ -1347,18 +1367,16 @@ public abstract class MappingInfo
Table foreign = rel.getTable();
boolean fullName = false;
boolean inverse = false;
if (name != null) {
int dotIdx = name.lastIndexOf('.');
if (dotIdx != -1) {
// allow use of '.' without prefix to mean "use expected
// foreign table"
if (dotIdx == 0)
if (!DBIdentifier.isNull(name)) {
QualifiedDBIdentifier path = QualifiedDBIdentifier.getPath(name);
if (!DBIdentifier.isNull(path.getObjectTableName())) {
if (DBIdentifier.isEmpty(path.getObjectTableName()))
local = foreign;
else
local = findTable(context, name.substring(0, dotIdx),
local = findTable(context, path.getObjectTableName(),
local, foreign, null);
fullName = true;
name = name.substring(dotIdx + 1);
name = path.getIdentifier().getUnqualifiedName();
// if inverse join, then swap local and foreign tables
if (local != table) {
@ -1375,28 +1393,27 @@ public abstract class MappingInfo
}
// determine target
String targetName = given.getTarget();
DBIdentifier targetName = given.getTargetIdentifier();
Object target = null;
Table ttable = null;
boolean constant = false;
boolean fullTarget = false;
if (targetName == null && given.getTargetField() != null) {
if (DBIdentifier.isNull(targetName) && given.getTargetField() != null) {
ClassMapping tcls = (inverse) ? cls : rel;
String fieldName = given.getTargetField();
int dotIdx = fieldName.lastIndexOf('.');
fullTarget = dotIdx != -1;
String[] names = Normalizer.splitName(fieldName);
fullTarget = names.length > 1;
if (dotIdx == 0) {
if (names.length > 1 && StringUtils.isEmpty(names[0])) {
// allow use of '.' without prefix to mean "use expected local
// cls"; but if we already inversed no need to switch again
if (!inverse)
tcls = cls;
fieldName = fieldName.substring(1);
} else if (dotIdx > 0) {
fieldName = names[1];
} else if (names.length > 1) {
// must be class + field name
tcls = findClassMapping(context, fieldName.substring
(0, dotIdx), cls, rel);
fieldName = fieldName.substring(dotIdx + 1);
tcls = findClassMapping(context, names[0], cls, rel);
fieldName = names[1];
}
if (tcls == null)
throw new MetaDataException(_loc.get(prefix
@ -1412,39 +1429,40 @@ public abstract class MappingInfo
+ "-fktargetfield-cols", context, fieldName, name));
ttable = (field.getJoinForeignKey() != null) ? field.getTable()
: field.getDefiningMapping().getTable();
targetName = field.getColumns()[0].getName();
} else if (targetName != null) {
if (targetName.charAt(0) == '\'') {
targetName = field.getColumns()[0].getIdentifier();
} else if (!DBIdentifier.isNull(targetName)) {
String targetNameStr = targetName.getName();
if (targetNameStr.charAt(0) == '\'') {
constant = true;
target = targetName.substring(1, targetName.length() - 1);
} else if (targetName.charAt(0) == '-'
|| targetName.charAt(0) == '.'
|| Character.isDigit(targetName.charAt(0))) {
target = targetNameStr.substring(1, targetNameStr.length() - 1);
} else if (targetNameStr.charAt(0) == '-'
|| targetNameStr.charAt(0) == '.'
|| Character.isDigit(targetNameStr.charAt(0))) {
constant = true;
try {
if (targetName.indexOf('.') == -1)
target = new Integer(targetName);
if (targetNameStr.indexOf('.') == -1)
target = new Integer(targetNameStr);
else
target = new Double(targetName);
target = new Double(targetNameStr);
} catch (RuntimeException re) {
throw new MetaDataException(_loc.get(prefix
+ "-bad-fkconst", context, targetName, name));
}
} else if ("null".equalsIgnoreCase(targetName))
} else if ("null".equalsIgnoreCase(targetNameStr))
constant = true;
else {
int dotIdx = targetName.lastIndexOf('.');
fullTarget = dotIdx != -1;
if (dotIdx == 0) {
QualifiedDBIdentifier path = QualifiedDBIdentifier.getPath(targetName);
fullTarget = (!DBIdentifier.isNull(path.getObjectTableName()));
if (!DBIdentifier.isNull(path.getObjectTableName()) &&
DBIdentifier.isEmpty(path.getObjectTableName())) {
// allow use of '.' without prefix to mean "use expected
// local table", but ignore if we're already inversed
if (!inverse)
ttable = local;
targetName = targetName.substring(1);
} else if (dotIdx != -1) {
ttable = findTable(context, targetName.substring(0,
dotIdx), foreign, local, (inverse) ? cls : rel);
targetName = targetName.substring(dotIdx + 1);
targetName = path.getIdentifier().getUnqualifiedName();
} else if (!DBIdentifier.isNull(path.getObjectTableName())) {
ttable = findTable(context, path.getObjectTableName(), foreign, local, (inverse) ? cls : rel);
targetName = path.getIdentifier().getUnqualifiedName();
}
}
}
@ -1468,7 +1486,7 @@ public abstract class MappingInfo
// in the column name, but not in the column target, or if the user
// gives no column name but a full target name
inverse = inverse || local != table || (local == foreign
&& ((fullName && !fullTarget) || (name == null && fullTarget)));
&& ((fullName && !fullTarget) || (DBIdentifier.isNull(name) && fullTarget)));
if (!inversable && !constant && inverse) {
if (local == foreign)
throw new MetaDataException(_loc.get(prefix
@ -1476,11 +1494,11 @@ public abstract class MappingInfo
throw new MetaDataException(_loc.get(prefix + "-bad-fk-inverse",
context, local, table));
}
if (name == null && constant)
if (DBIdentifier.isNull(name) && constant)
throw new MetaDataException(_loc.get(prefix
+ "-no-fkcol-name-adapt", context));
if (name == null && targetName == null) {
if (DBIdentifier.isNull(name) && DBIdentifier.isNull(targetName)) {
// if no name or target is provided and there's more than one likely
// join possibility, too ambiguous
PrimaryKey pk = foreign.getPrimaryKey();
@ -1489,13 +1507,13 @@ public abstract class MappingInfo
+ "-no-fkcol-name-adapt", context));
// assume target is pk column
targetName = pk.getColumns()[0].getName();
} else if (name != null && targetName == null) {
targetName = pk.getColumns()[0].getIdentifier();
} else if (!DBIdentifier.isNull(name) && DBIdentifier.isNull(targetName)) {
// if one primary key column use it for target; if multiple joins
// look for a foreign column with same name as local column
PrimaryKey pk = foreign.getPrimaryKey();
if (joins.length == 1 && pk != null && pk.getColumns().length == 1) {
targetName = pk.getColumns()[0].getName();
targetName = pk.getColumns()[0].getIdentifier();
}
else if (foreign.getColumn(name) != null) {
targetName = name;
@ -1509,15 +1527,15 @@ public abstract class MappingInfo
// find the target column, and create template for local column based
// on it
Column tmplate = new Column();
tmplate.setName(name);
tmplate.setIdentifier(name);
if (!constant) {
Column tcol = foreign.getColumn(targetName);
if (tcol == null)
throw new MetaDataException(_loc.get(prefix + "-bad-fktarget",
new Object[]{ context, targetName, name, foreign }));
if (name == null)
tmplate.setName(tcol.getName());
if (DBIdentifier.isNull(name))
tmplate.setIdentifier(tcol.getIdentifier());
tmplate.setJavaType(tcol.getJavaType());
tmplate.setType(tcol.getType());
tmplate.setTypeName(tcol.getTypeName());
@ -1535,8 +1553,8 @@ public abstract class MappingInfo
if (def != null)
def.populate(local, foreign, tmplate, target, inverse, idx,
joins.length);
if (name != null)
tmplate.setName(name);
if (!DBIdentifier.isNull(name))
tmplate.setIdentifier(name);
// create or merge local column
Column col = mergeColumn(context, prefix, tmplate, true, given, local,
@ -1589,7 +1607,7 @@ public abstract class MappingInfo
if (cols == null || cols.length == 0)
_cols = null;
else {
_cols = new ArrayList(cols.length);
_cols = new ArrayList<Column>(cols.length);
Column col;
for (int i = 0; i < cols.length; i++) {
col = syncColumn(context, cols[i], cols.length,
@ -1621,7 +1639,7 @@ public abstract class MappingInfo
_canIdx = true;
_idx = new Index();
_idx.setName(idx.getName());
_idx.setIdentifier(idx.getIdentifier());
_idx.setUnique(idx.isUnique());
if (idx.getColumns() != null && idx.getColumns().length > 1)
_idx.setColumns(idx.getColumns());
@ -1638,7 +1656,7 @@ public abstract class MappingInfo
_canUnq = true;
_unq = new Unique();
_unq.setName(unq.getName());
_unq.setIdentifier(unq.getIdentifier());
_unq.setDeferred(unq.isDeferred());
}
@ -1665,7 +1683,7 @@ public abstract class MappingInfo
else {
_canFK = true;
_fk = new ForeignKey();
_fk.setName(fk.getName());
_fk.setIdentifier(fk.getIdentifier());
_fk.setDeleteAction(fk.getDeleteAction());
_fk.setUpdateAction(fk.getUpdateAction());
_fk.setDeferred(fk.isDeferred());
@ -1679,7 +1697,7 @@ public abstract class MappingInfo
Object[] cpks = fk.getPrimaryKeyConstants();
int size = cols.length + ccols.length + cpkCols.length;
_cols = new ArrayList(size);
_cols = new ArrayList<Column>(size);
Column col;
for (int i = 0; i < cols.length; i++) {
col = syncColumn(context, cols[i], size, false, local,
@ -1725,27 +1743,28 @@ public abstract class MappingInfo
getDBDictionary();
Column copy = new Column();
if (col.getTable() != colTable || inverse)
copy.setName(dict.getFullName(col.getTable(), true)
+ dict.catalogSeparator + col.getName());
copy.setIdentifier(QualifiedDBIdentifier.newPath(dict.getFullIdentifier(col.getTable(), true),
col.getIdentifier()));
else
copy.setName(col.getName());
copy.setIdentifier(col.getIdentifier());
// set target if not default
if (target != null) {
if (target == NULL)
copy.setTarget("null");
copy.setTargetIdentifier(DBIdentifier.newColumn("null"));
else if (target instanceof Column) {
Column tcol = (Column) target;
if ((!inverse && tcol.getTable() != targetTable)
|| (inverse && tcol.getTable() != colTable))
copy.setTarget(dict.getFullName(tcol.getTable(), true)
+ dict.catalogSeparator + tcol.getName());
copy.setTargetIdentifier(
QualifiedDBIdentifier.newPath(dict.getFullIdentifier(tcol.getTable(), true),
tcol.getIdentifier()));
else if (!defaultTarget(col, tcol, num))
copy.setTarget(tcol.getName());
copy.setTargetIdentifier(tcol.getIdentifier());
} else if (target instanceof Number)
copy.setTarget(target.toString());
copy.setTargetIdentifier(DBIdentifier.newConstant(target.toString()));
else
copy.setTarget("'" + target + "'");
copy.setTargetIdentifier(DBIdentifier.newConstant("'" + target + "'"));
} else if (num > 1)
copy.setTargetField(col.getTargetField());
@ -1839,7 +1858,7 @@ public abstract class MappingInfo
*/
private static boolean defaultTarget(Column col, Column targetCol,
int num) {
if (col.getName().equals(targetCol.getName()))
if (col.getIdentifier().equals(targetCol.getIdentifier()))
return true;
if (num > 1)
return false;
@ -1857,8 +1876,10 @@ public abstract class MappingInfo
/**
* Return the default table name.
* @deprecated
*/
public String get(Schema schema);
public DBIdentifier getIdentifier(Schema schema);
}
/**

View File

@ -30,6 +30,7 @@ import java.util.Map;
import org.apache.openjpa.conf.OpenJPAConfiguration;
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.meta.strats.BlobValueHandler;
import org.apache.openjpa.jdbc.meta.strats.ByteArrayValueHandler;
import org.apache.openjpa.jdbc.meta.strats.CharArrayStreamValueHandler;
@ -112,7 +113,8 @@ public class MappingRepository extends MetaDataRepository {
private transient DBDictionary _dict = null;
private transient MappingDefaults _defaults = null;
private Map _results = new HashMap(); // object->queryresultmapping
// object->queryresultmapping
private Map<Object, QueryResultMapping> _results = new HashMap<Object, QueryResultMapping>();
private SchemaGroup _schema = null;
private StrategyInstaller _installer = null;
@ -344,11 +346,11 @@ public class MappingRepository extends MetaDataRepository {
* Return a unique key for the given class / name. The class argument
* can be null.
*/
private static Object getQueryResultKey(Class cls, String name) {
private static Object getQueryResultKey(Class<?> cls, String name) {
return getQueryKey(cls, name);
}
public ClassMapping getMapping(Class cls, ClassLoader envLoader,
public ClassMapping getMapping(Class<?> cls, ClassLoader envLoader,
boolean mustExist) {
return (ClassMapping) super.getMetaData(cls, envLoader, mustExist);
}
@ -362,7 +364,7 @@ public class MappingRepository extends MetaDataRepository {
return (ClassMapping) super.getMetaData(oid, envLoader, mustExist);
}
public ClassMapping[] getImplementorMappings(Class cls,
public ClassMapping[] getImplementorMappings(Class<?> cls,
ClassLoader envLoader, boolean mustExist) {
return (ClassMapping[]) super.getImplementorMetaDatas(cls, envLoader,
mustExist);
@ -415,7 +417,7 @@ public class MappingRepository extends MetaDataRepository {
mapping.resolveNonRelationMappings();
}
protected ClassMetaData newClassMetaData(Class type) {
protected ClassMetaData newClassMetaData(Class<?> type) {
return new ClassMapping(type, this);
}
@ -423,7 +425,7 @@ public class MappingRepository extends MetaDataRepository {
return new ClassMapping[length];
}
protected FieldMetaData newFieldMetaData(String name, Class type,
protected FieldMetaData newFieldMetaData(String name, Class<?> type,
ClassMetaData owner) {
return new FieldMapping(name, type, (ClassMapping) owner);
}
@ -530,7 +532,7 @@ public class MappingRepository extends MetaDataRepository {
String props = Configurations.getProperties(name);
name = Configurations.getClassName(name);
Class strat = null;
Class<?> strat = null;
// base and vertical strategies use same alias; differentiate on join
if (FullClassStrategy.ALIAS.equals(name))
@ -575,7 +577,7 @@ public class MappingRepository extends MetaDataRepository {
String props = Configurations.getProperties(name);
name = Configurations.getClassName(name);
try {
Class c = JavaTypes.classForName(name, field,
Class<?> c = JavaTypes.classForName(name, field,
AccessController.doPrivileged(
J2DoPrivHelper.getClassLoaderAction(FieldStrategy.class)));
if (FieldStrategy.class.isAssignableFrom(c)) {
@ -636,7 +638,7 @@ public class MappingRepository extends MetaDataRepository {
String props = Configurations.getProperties(name);
name = Configurations.getClassName(name);
Class strat = null;
Class<?> strat = null;
if (ClassNameDiscriminatorStrategy.ALIAS.equals(name))
strat = ClassNameDiscriminatorStrategy.class;
@ -698,7 +700,7 @@ public class MappingRepository extends MetaDataRepository {
String props = Configurations.getProperties(name);
name = Configurations.getClassName(name);
Class strat = null;
Class<?> strat = null;
if (NumberVersionStrategy.ALIAS.equals(name))
strat = NumberVersionStrategy.class;
@ -729,7 +731,7 @@ public class MappingRepository extends MetaDataRepository {
/**
* Instantiate the given version strategy.
*/
protected VersionStrategy instantiateVersionStrategy(Class strat,
protected VersionStrategy instantiateVersionStrategy(Class<?> strat,
Version version, String props) {
try {
VersionStrategy strategy = (VersionStrategy)
@ -824,7 +826,7 @@ public class MappingRepository extends MetaDataRepository {
protected FieldStrategy defaultStrategy(FieldMapping field,
boolean installHandlers, boolean adapting) {
// not persistent?
if (field.getManagement() != field.MANAGE_PERSISTENT
if (field.getManagement() != FieldMetaData.MANAGE_PERSISTENT
|| field.isVersion())
return NoneFieldStrategy.getInstance();
if (field.getDefiningMapping().getStrategy() ==
@ -1038,7 +1040,7 @@ public class MappingRepository extends MetaDataRepository {
// an association table
FieldMappingInfo info = field.getMappingInfo();
ValueMapping elem = field.getElementMapping();
boolean useInverseKeyMapping = info.getTableName() == null && info.getColumns().isEmpty()
boolean useInverseKeyMapping = DBIdentifier.isNull(info.getTableIdentifier()) && info.getColumns().isEmpty()
&& !elem.getValueInfo().getColumns().isEmpty();
// JPA 2.0: non-default mapping: uni-/1-M/JoinColumn ==> foreign key strategy
@ -1157,7 +1159,7 @@ public class MappingRepository extends MetaDataRepository {
}
public boolean hasJoinTable(FieldMapping field) {
boolean hasJoinTable = field.getMappingInfo().getTableName() != null ? true : false;
boolean hasJoinTable = !DBIdentifier.isNull(field.getMappingInfo().getTableIdentifier()) ? true : false;
return hasJoinTable;
}
@ -1179,7 +1181,7 @@ public class MappingRepository extends MetaDataRepository {
/**
* Check the given value against mapped strategies.
*/
private Object mappedStrategy(ValueMapping val, Class type,
private Object mappedStrategy(ValueMapping val, Class<?> type,
boolean adapting) {
if (type == null || type == Object.class)
return null;
@ -1200,7 +1202,7 @@ public class MappingRepository extends MetaDataRepository {
String props = Configurations.getProperties(name);
name = Configurations.getClassName(name);
try {
Class c = JavaTypes.classForName(name, val,
Class<?> c = JavaTypes.classForName(name, val,
AccessController.doPrivileged(
J2DoPrivHelper.getClassLoaderAction(FieldStrategy.class)));
Object o = AccessController.doPrivileged(
@ -1227,7 +1229,7 @@ public class MappingRepository extends MetaDataRepository {
String props = Configurations.getProperties(name);
name = Configurations.getClassName(name);
try {
Class c = JavaTypes.classForName(name, val,
Class<?> c = JavaTypes.classForName(name, val,
AccessController.doPrivileged(
J2DoPrivHelper.getClassLoaderAction(ValueHandler.class)));
if (ValueHandler.class.isAssignableFrom(c)) {
@ -1344,7 +1346,7 @@ public class MappingRepository extends MetaDataRepository {
* Checks for hints as to whether the given column is a CLOB.
*/
private boolean isClob(ValueMapping val, boolean warn) {
List cols = val.getValueInfo().getColumns();
List<Column> cols = val.getValueInfo().getColumns();
if (cols.size() != 1)
return false;
@ -1511,12 +1513,12 @@ public class MappingRepository extends MetaDataRepository {
// persistent subclasses may not have been resolved yet.
// run through the persistent types to see if any of them
// or their superclass is a subclass of this class.
Collection classes = loadPersistentTypes(false,
Collection<Class<?>> classes = loadPersistentTypes(false,
mapping.getEnvClassLoader());
Class cls;
for (Iterator itr = classes.iterator(); itr.hasNext();) {
cls = (Class) itr.next();
Class supcl = cls.getSuperclass();
Class<?> cls;
for (Iterator<Class<?>> itr = classes.iterator(); itr.hasNext();) {
cls = itr.next();
Class<?> supcl = cls.getSuperclass();
while (supcl != null &&
!supcl.getClass().equals(java.lang.Object.class)) {
if (!supcl.isInterface() &&

View File

@ -18,6 +18,8 @@
*/
package org.apache.openjpa.jdbc.meta;
import org.apache.openjpa.meta.MetaDataModes;
/**
* Installer used during mapping that attempts to use the given mapping
* information (if any), and fails if it does not work.
@ -26,6 +28,7 @@ package org.apache.openjpa.jdbc.meta;
* @nojavadoc
* @since 0.4.0
*/
@SuppressWarnings("serial")
public class MappingStrategyInstaller
extends StrategyInstaller {
@ -45,7 +48,7 @@ public class MappingStrategyInstaller
if (strat == null)
strat = repos.defaultStrategy(cls, true);
cls.setStrategy(strat, Boolean.TRUE);
cls.setSourceMode(cls.MODE_MAPPING, true);
cls.setSourceMode(MetaDataModes.MODE_MAPPING, true);
}
public void installStrategy(FieldMapping field) {

View File

@ -52,6 +52,8 @@ import org.apache.openjpa.kernel.Seq;
import org.apache.openjpa.lib.conf.Configurations;
import org.apache.openjpa.lib.log.Log;
import org.apache.openjpa.lib.meta.ClassArgParser;
import org.apache.openjpa.lib.meta.MetaDataSerializer;
import org.apache.openjpa.lib.meta.SourceTracker;
import org.apache.openjpa.lib.util.Files;
import org.apache.openjpa.lib.util.J2DoPrivHelper;
import org.apache.openjpa.lib.util.Localizer;
@ -62,6 +64,7 @@ import org.apache.openjpa.meta.FieldMetaData;
import org.apache.openjpa.meta.JavaTypes;
import org.apache.openjpa.meta.MetaDataFactory;
import org.apache.openjpa.meta.MetaDataModes;
import org.apache.openjpa.meta.MetaDataRepository;
import org.apache.openjpa.meta.QueryMetaData;
import org.apache.openjpa.meta.SequenceMetaData;
import org.apache.openjpa.meta.ValueStrategies;
@ -123,8 +126,8 @@ public class MappingTool
private Writer _schemaWriter = null;
// buffer metadatas to be dropped
private Set _dropCls = null;
private Set _dropMap = null;
private Set<Class<?>> _dropCls = null;
private Set<ClassMapping> _dropMap = null;
private boolean _flush = false;
private boolean _flushSchema = false;
@ -377,7 +380,7 @@ public class MappingTool
if (_repos == null) {
_repos = _conf.newMappingRepositoryInstance();
_repos.setSchemaGroup(getSchemaGroup());
_repos.setValidate(_repos.VALIDATE_UNENHANCED, false);
_repos.setValidate(MetaDataRepository.VALIDATE_UNENHANCED, false);
}
return _repos;
}
@ -467,7 +470,7 @@ public class MappingTool
try {
if (_dropCls != null && !_dropCls.isEmpty()) {
Class[] cls = (Class[]) _dropCls.toArray
Class<?>[] cls = (Class[]) _dropCls.toArray
(new Class[_dropCls.size()]);
if (!io.drop(cls, _mode, null))
_log.warn(_loc.get("bad-drop", _dropCls));
@ -508,7 +511,7 @@ public class MappingTool
// serialize the planned schema to the stream
SchemaSerializer ser = new XMLSchemaSerializer(_conf);
ser.addAll(getSchemaGroup());
ser.serialize(_schemaWriter, ser.PRETTY);
ser.serialize(_schemaWriter, MetaDataSerializer.PRETTY);
_schemaWriter.flush();
}
}
@ -517,21 +520,21 @@ public class MappingTool
QueryMetaData[] queries = repos.getQueryMetaDatas();
SequenceMetaData[] seqs = repos.getSequenceMetaDatas();
Map output = null;
Map<File, String> output = null;
// if we're outputting to stream, set all metas to same file so
// they get placed in single string
if (_mappingWriter != null) {
output = new HashMap();
output = new HashMap<File, String>();
File tmp = new File("openjpatmp");
for (int i = 0; i < mappings.length; i++)
mappings[i].setSource(tmp, mappings[i].SRC_OTHER);
mappings[i].setSource(tmp, SourceTracker.SRC_OTHER);
for (int i = 0; i < queries.length; i++)
queries[i].setSource(tmp, queries[i].getSourceScope(),
queries[i].SRC_OTHER);
SourceTracker.SRC_OTHER);
for (int i = 0; i < seqs.length; i++)
seqs[i].setSource(tmp, seqs[i].getSourceScope(),
seqs[i].SRC_OTHER);
SourceTracker.SRC_OTHER);
}
// store
@ -541,9 +544,9 @@ public class MappingTool
// write to stream
if (_mappingWriter != null) {
PrintWriter out = new PrintWriter(_mappingWriter);
for (Iterator itr = output.values().iterator();
for (Iterator<String> itr = output.values().iterator();
itr.hasNext();)
out.println((String) itr.next());
out.println(itr.next());
out.flush();
}
}
@ -634,7 +637,7 @@ public class MappingTool
/**
* Run the configured action on the given instance.
*/
public void run(Class cls) {
public void run(Class<?> cls) {
if (ACTION_ADD.equals(_action)) {
if (_meta)
addMeta(cls);
@ -653,7 +656,7 @@ public class MappingTool
/**
* Add the mapping for the given instance.
*/
private void add(Class cls) {
private void add(Class<?> cls) {
if (cls == null)
return;
@ -669,7 +672,7 @@ public class MappingTool
* Return the mapping for the given type, or null if the type is
* persistence-aware.
*/
private static ClassMapping getMapping(MappingRepository repos, Class cls,
private static ClassMapping getMapping(MappingRepository repos, Class<?> cls,
boolean validate) {
// this will parse all possible metadata rsrcs looking for cls, so
// will detect if p-aware
@ -685,7 +688,7 @@ public class MappingTool
/**
* Create a metadata for the given instance.
*/
private void addMeta(Class cls) {
private void addMeta(Class<?> cls) {
if (cls == null)
return;
@ -710,7 +713,7 @@ public class MappingTool
/**
* Refresh or add the mapping for the given instance.
*/
private void refresh(Class cls) {
private void refresh(Class<?> cls) {
if (cls == null)
return;
@ -725,7 +728,7 @@ public class MappingTool
/**
* Validate the mappings for the given class and its fields.
*/
private void validate(Class cls) {
private void validate(Class<?> cls) {
if (cls == null)
return;
@ -739,7 +742,7 @@ public class MappingTool
/**
* Create the schema using the mapping for the given instance.
*/
private void buildSchema(Class cls) {
private void buildSchema(Class<?> cls) {
if (cls == null)
return;
@ -770,12 +773,12 @@ public class MappingTool
/**
* Drop mapping for given class.
*/
private void drop(Class cls) {
private void drop(Class<?> cls) {
if (cls == null)
return;
if (_dropCls == null)
_dropCls = new HashSet();
_dropCls = new HashSet<Class<?>>();
_dropCls.add(cls);
if (!contains(_schemaActions,SchemaTool.ACTION_DROP))
return;
@ -791,7 +794,7 @@ public class MappingTool
if (mapping != null) {
_flushSchema = true;
if (_dropMap == null)
_dropMap = new HashSet();
_dropMap = new HashSet<ClassMapping>();
_dropMap.add(mapping);
} else
_log.warn(_loc.get("no-drop-meta", cls));
@ -1003,7 +1006,7 @@ public class MappingTool
// collect the classes to act on
Log log = conf.getLog(OpenJPAConfiguration.LOG_TOOL);
Collection classes = null;
Collection<Class<?>> classes = null;
if (args.length == 0) {
if (ACTION_IMPORT.equals(flags.action))
return false;
@ -1011,18 +1014,18 @@ public class MappingTool
classes = conf.getMappingRepositoryInstance().
loadPersistentTypes(true, loader);
} else {
classes = new HashSet();
classes = new HashSet<Class<?>>();
ClassArgParser classParser = conf.getMetaDataRepositoryInstance().
getMetaDataFactory().newClassArgParser();
classParser.setClassLoader(loader);
Class[] parsed;
Class<?>[] parsed;
for (int i = 0; args != null && i < args.length; i++) {
parsed = classParser.parseTypes(args[i]);
classes.addAll(Arrays.asList(parsed));
}
}
Class[] act = (Class[]) classes.toArray(new Class[classes.size()]);
Class<?>[] act = (Class[]) classes.toArray(new Class[classes.size()]);
if (ACTION_EXPORT.equals(flags.action)) {
// run exports until the first export succeeds
ImportExport[] instances = newImportExports();
@ -1081,7 +1084,7 @@ public class MappingTool
*/
private static ImportExport[] newImportExports() {
try {
Class[] types = Services.getImplementorClasses(ImportExport.class);
Class<?>[] types = Services.getImplementorClasses(ImportExport.class);
ImportExport[] instances = new ImportExport[types.length];
for (int i = 0; i < types.length; i++)
instances[i] = (ImportExport) AccessController.doPrivileged(
@ -1129,14 +1132,14 @@ public class MappingTool
/**
* Import mappings for the given classes based on the given arguments.
*/
public boolean importMappings(JDBCConfiguration conf, Class[] act,
public boolean importMappings(JDBCConfiguration conf, Class<?>[] act,
String[] args, boolean meta, Log log, ClassLoader loader)
throws IOException;
/**
* Export mappings for the given classes based on the given arguments.
*/
public boolean exportMappings(JDBCConfiguration conf, Class[] act,
public boolean exportMappings(JDBCConfiguration conf, Class<?>[] act,
boolean meta, Log log, Writer writer)
throws IOException;
}

View File

@ -18,6 +18,7 @@
*/
package org.apache.openjpa.jdbc.meta;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.ForeignKey;
import org.apache.openjpa.jdbc.schema.Index;
@ -63,7 +64,7 @@ public class NoneMappingDefaults
return null;
}
public Object getStrategy(ValueMapping vm, Class type, boolean adapt) {
public Object getStrategy(ValueMapping vm, Class<?> type, boolean adapt) {
return null;
}
@ -98,11 +99,17 @@ public class NoneMappingDefaults
Column col, Object target, int pos, int cols) {
}
/**
* @deprecated
*/
public void populateForeignKeyColumn(ValueMapping vm, String name,
Table local, Table foreign, Column col, Object target, boolean inverse,
int pos, int cols) {
}
/**
* @deprecated
*/
public void populateColumns(ValueMapping vm, String name, Table table,
Column[] cols) {
}
@ -112,6 +119,9 @@ public class NoneMappingDefaults
return false;
}
/**
* @deprecated
*/
public boolean populateNullIndicatorColumns(ValueMapping vm, String name,
Table table, Column[] cols) {
return false;
@ -127,6 +137,9 @@ public class NoneMappingDefaults
return null;
}
/**
* @deprecated
*/
public ForeignKey getForeignKey(ValueMapping vm, String name, Table local,
Table foreign, boolean inverse) {
return null;
@ -164,4 +177,45 @@ public class NoneMappingDefaults
public void installPrimaryKey(FieldMapping fm, Table table) {
}
public ForeignKey getForeignKey(ValueMapping vm, DBIdentifier name, Table local,
Table foreign, boolean inverse) {
return null;
}
public Index getIndex(ValueMapping vm, DBIdentifier name, Table table,
Column[] cols) {
return null;
}
public Unique getUnique(ValueMapping vm, DBIdentifier name, Table table,
Column[] cols) {
return null;
}
public void populateColumns(ValueMapping vm, DBIdentifier name, Table table,
Column[] cols) {
}
public void populateForeignKeyColumn(ValueMapping vm, DBIdentifier name,
Table local, Table foreign, Column col, Object target, boolean inverse,
int pos, int cols) {
}
public boolean populateNullIndicatorColumns(ValueMapping vm, DBIdentifier name,
Table table, Column[] cols) {
return false;
}
public DBIdentifier getTableIdentifier(ClassMapping cls, Schema defaultSchema) {
return DBIdentifier.newTable(getTableName(cls, defaultSchema));
}
public DBIdentifier getTableIdentifier(FieldMapping fm, Schema defaultSchema) {
return DBIdentifier.newTable(getTableName(fm, defaultSchema));
}
public DBIdentifier getPrimaryKeyIdentifier(ClassMapping cm, Table table) {
return DBIdentifier.NULL;
}
}

View File

@ -100,7 +100,7 @@ import serp.bytecode.Project;
import serp.util.Strings;
/**
* Reverse-maps a schema into class mappings and the assiciated java
* Reverse-maps a schema into class mappings and the associated java
* code. Generates a Java code files for persistent classes and associated
* identity classes and metadata.
*

View File

@ -19,18 +19,16 @@
package org.apache.openjpa.jdbc.meta;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.apache.openjpa.conf.OpenJPAConfiguration;
import org.apache.openjpa.jdbc.conf.JDBCSeqValue;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.identifier.DBIdentifier.DBIdentifierType;
import org.apache.openjpa.jdbc.kernel.ClassTableJDBCSeq;
import org.apache.openjpa.jdbc.kernel.TableJDBCSeq;
import org.apache.openjpa.jdbc.kernel.ValueTableJDBCSeq;
import org.apache.openjpa.jdbc.schema.Unique;
import org.apache.openjpa.lib.conf.PluginValue;
import org.apache.openjpa.lib.identifier.IdentifierUtil;
import org.apache.openjpa.meta.SequenceMetaData;
/**
@ -38,6 +36,7 @@ import org.apache.openjpa.meta.SequenceMetaData;
*
* @author Abe White
*/
@SuppressWarnings("serial")
public class SequenceMapping
extends SequenceMetaData {
@ -65,17 +64,32 @@ public class SequenceMapping
private static final String PROP_UNIQUE_CONSTRAINT = "UniqueConstraintName";
private File _mapFile = null;
private String _table = null;
private String _sequenceColumn = null;
private String _primaryKeyColumn = null;
private DBIdentifier _table = DBIdentifier.NULL;
private DBIdentifier _sequenceColumn = DBIdentifier.NULL;
private DBIdentifier _primaryKeyColumn = DBIdentifier.NULL;
private String _primaryKeyValue = null;
private String[] _uniqueColumns = null;
private String _uniqueConstraintName = null;
private DBIdentifier[] _uniqueColumns = null;
private DBIdentifier _uniqueConstraintName = DBIdentifier.NULL;
/**
* @deprecated
* @param name
* @param repos
*/
public SequenceMapping(String name, MappingRepository repos) {
super(name, repos);
}
/**
* Sequence names are a kernel object so DBIdentifiers must be converted to
* strings
* @param name
* @param repos
*/
public SequenceMapping(DBIdentifier name, MappingRepository repos) {
super(DBIdentifier.isNull(name) ? null : name.getName(), repos);
}
/**
* Allow sequence to have a mapping file separate from its metadata
* source file.
@ -94,43 +108,73 @@ public class SequenceMapping
/**
* Name of sequence table, if any.
* @deprecated
*/
public String getTable() {
return _table;
return getTableIdentifier().getName();
}
public DBIdentifier getTableIdentifier() {
return _table == null ? DBIdentifier.NULL : _table ;
}
/**
* Name of sequence table, if any.
* @deprecated
*/
public void setTable(String table) {
setTableIdentifier(DBIdentifier.newTable(table));
}
public void setTableIdentifier(DBIdentifier table) {
_table = table;
}
/**
* Name of sequence column, if any.
* @deprecated
*/
public String getSequenceColumn() {
return _sequenceColumn;
return getSequenceColumnIdentifier().getName();
}
public DBIdentifier getSequenceColumnIdentifier() {
return _sequenceColumn == null ? DBIdentifier.NULL : _sequenceColumn;
}
/**
* Name of sequence column, if any.
* @deprecated
*/
public void setSequenceColumn(String sequenceColumn) {
setSequenceColumnIdentifier(DBIdentifier.newColumn(sequenceColumn));
}
public void setSequenceColumnIdentifier(DBIdentifier sequenceColumn) {
_sequenceColumn = sequenceColumn;
}
/**
* Name of primary key column, if any.
* @deprecated
*/
public String getPrimaryKeyColumn() {
return _primaryKeyColumn;
return getPrimaryKeyColumnIdentifier().getName();
}
public DBIdentifier getPrimaryKeyColumnIdentifier() {
return _primaryKeyColumn == null ? DBIdentifier.NULL : _primaryKeyColumn;
}
/**
* Name of primary key column, if any.
* @deprecated
*/
public void setPrimaryKeyColumn(String primaryKeyColumn) {
setPrimaryKeyColumnIdentifier(DBIdentifier.newColumn(primaryKeyColumn));
}
public void setPrimaryKeyColumnIdentifier(DBIdentifier primaryKeyColumn) {
_primaryKeyColumn = primaryKeyColumn;
}
@ -148,13 +192,29 @@ public class SequenceMapping
_primaryKeyValue = primaryKeyValue;
}
/**
* @deprecated
* @param cols
*/
public void setUniqueColumns(String[] cols) {
_uniqueColumns = cols;
setUniqueColumnsIdentifier(DBIdentifier.toArray(cols, DBIdentifierType.COLUMN));
}
public void setUniqueColumnsIdentifier(DBIdentifier[] cols) {
_uniqueColumns = cols;
}
/**
* @deprecated
*/
public String[] getUniqueColumns() {
return DBIdentifier.toStringArray(getUniqueColumnsIdentifier());
}
public DBIdentifier[] getUniqueColumnsIdentifier() {
return _uniqueColumns;
}
protected PluginValue newPluginValue(String property) {
return new JDBCSeqValue(property);
@ -170,17 +230,17 @@ public class SequenceMapping
// set preserves the intended ones. While this is an ugly solution,
// it's less ugly than other ones.
appendProperty(props, PROP_TABLE, addQuotes(_table));
appendProperty(props, PROP_SEQUENCE_COL, addQuotes(_sequenceColumn));
appendProperty(props, PROP_PK_COL, addQuotes(_primaryKeyColumn));
appendProperty(props, PROP_TABLE, addQuotes(_table.getName()));
appendProperty(props, PROP_SEQUENCE_COL, addQuotes(_sequenceColumn.getName()));
appendProperty(props, PROP_PK_COL, addQuotes(_primaryKeyColumn.getName()));
appendProperty(props, PROP_PK_VALUE, addQuotes(_primaryKeyValue));
// Array of unique column names are passed to configuration
// as a single string "x|y|z". The configurable (TableJDBCSeq) must
// parse it back.
if (_uniqueConstraintName != null &&
_uniqueConstraintName.length() > 0) {
if (!DBIdentifier.isNull(_uniqueConstraintName) &&
_uniqueConstraintName.getName().length() > 0) {
appendProperty(props, PROP_UNIQUE_CONSTRAINT,
addQuotes(_uniqueConstraintName));
addQuotes(_uniqueConstraintName.getName()));
}
if (_uniqueColumns != null && _uniqueColumns.length > 0)
@ -189,19 +249,34 @@ public class SequenceMapping
}
private String addQuotes(String name) {
if (name != null && name.startsWith("\"") && name.endsWith("\"")) {
return "\"" + name + "\"";
if (name != null && name.contains(IdentifierUtil.DOUBLE_QUOTE)) {
return IdentifierUtil.DOUBLE_QUOTE + name + IdentifierUtil.DOUBLE_QUOTE;
}
return name;
}
/**
* @deprecated
* @param name
*/
public void setUniqueConstraintName(String name) {
_uniqueConstraintName = name;
_uniqueConstraintName = DBIdentifier.newConstraint(name);
}
public void setUniqueConstraintIdentifier(DBIdentifier name) {
_uniqueConstraintName = name;
}
/**
* @deprecated
* @return
*/
public String getUniqueConstraintName() {
return _uniqueConstraintName;
return getUniqueConstraintIdentifier().getName();
}
public DBIdentifier getUniqueConstraintIdentifier() {
return _uniqueConstraintName == null ? DBIdentifier.NULL : _uniqueConstraintName;
}
}

View File

@ -21,6 +21,7 @@ package org.apache.openjpa.jdbc.meta;
import java.io.Serializable;
import java.sql.SQLException;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.ColumnIO;
import org.apache.openjpa.jdbc.schema.ForeignKey;
@ -249,9 +250,17 @@ public interface ValueMapping
* Map indexes and constraints for this value, using the current
* {@link ValueMappingInfo}. The foreign key or columns of this value
* must be set before calling this method.
* @deprecated
*/
public void mapConstraints(String name, boolean adapt);
/**
* Map indexes and constraints for this value, using the current
* {@link ValueMappingInfo}. The foreign key or columns of this value
* must be set before calling this method.
*/
public void mapConstraints(DBIdentifier name, boolean adapt);
/**
* Clear mapping information, including strategy.
*/

View File

@ -22,6 +22,7 @@ import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.ColumnIO;
import org.apache.openjpa.jdbc.schema.ForeignKey;
@ -45,6 +46,7 @@ import org.apache.openjpa.util.MetaDataException;
* @author Abe White
* @since 0.4.0
*/
@SuppressWarnings("serial")
public class ValueMappingImpl
extends ValueMetaDataImpl
implements ValueMapping {
@ -59,7 +61,7 @@ public class ValueMappingImpl
private Column[] _cols = Schemas.EMPTY_COLUMNS;
private ColumnIO _io = null;
private ForeignKey _fk = null;
private Map _targetFKs = null;
private Map<ClassMapping,ForeignKey> _targetFKs = null;
private Index _idx = null;
private Unique _unq = null;
private int _join = JOIN_FORWARD;
@ -188,7 +190,7 @@ public class ValueMappingImpl
if (cachedFK != null)
return (ForeignKey) cachedFK;
} else
_targetFKs = new HashMap();
_targetFKs = new HashMap<ClassMapping, ForeignKey>();
ForeignKey newfk = (_join == JOIN_FORWARD)
? newForwardForeignKey(target) : newInverseForeignKey(target);
@ -220,12 +222,12 @@ public class ValueMappingImpl
cols[i].getTargetField());
else if (_fk != null)
tcols[i] = getEquivalentColumn(_fk.getPrimaryKeyColumn
(cols[i]).getName(), target, true);
else if (cols[i].getTarget() != null)
tcols[i] = getEquivalentColumn(cols[i].getTarget(), target,
(cols[i]).getIdentifier(), target, true);
else if (!DBIdentifier.isNull(cols[i].getTargetIdentifier()))
tcols[i] = getEquivalentColumn(cols[i].getTargetIdentifier(), target,
true);
else
tcols[i] = getEquivalentColumn(cols[i].getName(), target,
tcols[i] = getEquivalentColumn(cols[i].getIdentifier(), target,
false);
}
@ -239,7 +241,7 @@ public class ValueMappingImpl
cols = _fk.getConstantPrimaryKeyColumns();
for (int i = 0; i < cols.length; i++)
newfk.joinConstant(_fk.getPrimaryKeyConstant(cols[i]),
getEquivalentColumn(cols[i].getName(), target, true));
getEquivalentColumn(cols[i].getIdentifier(), target, true));
}
return newfk;
}
@ -267,7 +269,7 @@ public class ValueMappingImpl
/**
* Return the given mapping's equivalent of the given column.
*/
private Column getEquivalentColumn(String colName, ClassMapping target,
private Column getEquivalentColumn(DBIdentifier colName, ClassMapping target,
boolean explicit) {
// if there was no explicit target, use single pk column
if (!explicit) {
@ -433,11 +435,18 @@ public class ValueMappingImpl
embed.refSchemaComponents();
}
/**
* @deprecated
*/
public void mapConstraints(String name, boolean adapt) {
mapConstraints(DBIdentifier.newConstraint(name), adapt);
}
public void mapConstraints(DBIdentifier name, boolean adapt) {
_unq = _info.getUnique(this, name, adapt);
_idx = _info.getIndex(this, name, adapt);
}
public void clearMapping() {
_handler = null;
_cols = Schemas.EMPTY_COLUMNS;

View File

@ -21,6 +21,7 @@ package org.apache.openjpa.jdbc.meta;
import java.util.Collections;
import java.util.List;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.ColumnIO;
import org.apache.openjpa.jdbc.schema.ForeignKey;
@ -40,6 +41,7 @@ import org.apache.openjpa.util.MetaDataException;
*
* @author Abe White
*/
@SuppressWarnings("serial")
public class ValueMappingInfo
extends MappingInfo {
@ -48,7 +50,7 @@ public class ValueMappingInfo
private boolean _criteria = false;
private boolean _canNull = true;
private List _mapsIdCols = null;
private List<Column> _mapsIdCols = null;
/**
* Whether to use class criteria when joining to related type.
@ -83,8 +85,14 @@ public class ValueMappingInfo
*
* @param name base name for value mapping
* @param inversable whether an inverse join is allowed
* @deprecated
*/
public ForeignKey getTypeJoin(final ValueMapping val, final String name,
boolean inversable, boolean adapt) {
return getTypeJoin(val, DBIdentifier.newForeignKey(name), inversable, adapt);
}
public ForeignKey getTypeJoin(final ValueMapping val, final DBIdentifier name,
boolean inversable, boolean adapt) {
ClassMapping rel = val.getTypeMapping();
if (rel == null)
@ -123,9 +131,15 @@ public class ValueMappingInfo
/**
* Return the join from the related type to this value.
* @deprecated
*/
public ForeignKey getInverseTypeJoin(final ValueMapping val,
final String name, boolean adapt) {
return getInverseTypeJoin(val, DBIdentifier.newForeignKey(name), adapt);
}
public ForeignKey getInverseTypeJoin(final ValueMapping val,
final DBIdentifier name, boolean adapt) {
ClassMapping rel = val.getTypeMapping();
if (rel == null || rel.getTable() == null)
return null;
@ -149,8 +163,14 @@ public class ValueMappingInfo
/**
* Return the columns for this value, based on the given templates.
* @deprecated
*/
public Column[] getColumns(ValueMapping val, String name,
Column[] tmplates, Table table, boolean adapt) {
return getColumns(val, DBIdentifier.newColumn(name), tmplates, table, adapt);
}
public Column[] getColumns(ValueMapping val, DBIdentifier name,
Column[] tmplates, Table table, boolean adapt) {
orderColumnsByTargetField(val, tmplates, adapt);
val.getMappingRepository().getMappingDefaults().populateColumns
@ -166,7 +186,7 @@ public class ValueMappingInfo
boolean adapt) {
if (tmplates.length < 2 || tmplates[0].getTargetField() == null)
return;
List cols = getColumns();
List<Column> cols = getColumns();
if (cols.isEmpty() || cols.size() != tmplates.length)
return;
@ -200,8 +220,13 @@ public class ValueMappingInfo
/**
* Return a unique constraint for the given columns, or null if none.
* @deprecated
*/
public Unique getUnique(ValueMapping val, String name, boolean adapt) {
return getUnique(val, DBIdentifier.newConstraint(name), adapt);
}
public Unique getUnique(ValueMapping val, DBIdentifier name, boolean adapt) {
Column[] cols = val.getColumns();
if (cols.length == 0)
return null;
@ -213,8 +238,13 @@ public class ValueMappingInfo
/**
* Return an index for the given columns, or null if none.
* @deprecated
*/
public Index getIndex(ValueMapping val, String name, boolean adapt) {
return getIndex(val, DBIdentifier.newIndex(name), adapt);
}
public Index getIndex(ValueMapping val, DBIdentifier name, boolean adapt) {
Column[] cols = val.getColumns();
if (cols.length == 0)
return null;
@ -226,8 +256,14 @@ public class ValueMappingInfo
/**
* Return the null indicator column for this value, or null if none.
* @deprecated
*/
public Column getNullIndicatorColumn(ValueMapping val, String name,
Table table, boolean adapt) {
return getNullIndicatorColumn(val, DBIdentifier.newColumn(name), table, adapt);
}
public Column getNullIndicatorColumn(ValueMapping val, DBIdentifier name,
Table table, boolean adapt) {
// reset IO
setColumnIO(null);
@ -237,14 +273,15 @@ public class ValueMappingInfo
return null;
// extract given null-ind column
List cols = getColumns();
List<Column> cols = getColumns();
Column given = (cols.isEmpty()) ? null : (Column) cols.get(0);
MappingDefaults def = val.getMappingRepository().getMappingDefaults();
if (given == null && (!adapt && !def.defaultMissingInfo()))
return null;
Column tmplate = new Column();
tmplate.setName(name + "_null");
DBIdentifier sName = DBIdentifier.append(name, "_null");
tmplate.setIdentifier(sName);
tmplate.setJavaType(JavaTypes.INT);
if (!def.populateNullIndicatorColumns(val, name, table, new Column[]
{ tmplate }) && given == null)
@ -258,17 +295,17 @@ public class ValueMappingInfo
setColumnIO(io);
}
if (given != null && given.getName() != null) {
if (given != null && !DBIdentifier.isNull(given.getIdentifier())) {
// test if given column name is actually a field name, in which
// case we use its column as the null indicator column
ClassMapping embed = val.getEmbeddedMapping();
FieldMapping efm = (embed == null) ? null
: embed.getFieldMapping(given.getName());
: embed.getFieldMapping(given.getIdentifier().getName());
if (efm != null && efm.getColumns().length > 0)
given.setName(efm.getColumns()[0].getName());
given.setIdentifier(efm.getColumns()[0].getIdentifier());
}
boolean compat = given == null || given.getName() == null
|| table == null || !table.isNameTaken(given.getName());
boolean compat = given == null || DBIdentifier.isNull(given.getIdentifier())
|| table == null || !table.isNameTaken(given.getIdentifier());
return mergeColumn(val, "null-ind", tmplate, compat, given,
table, adapt, def.defaultMissingInfo());
@ -295,7 +332,7 @@ public class ValueMappingInfo
setJoinDirection(JOIN_FORWARD);
} else {
foreign = val.getTypeMapping().getTable();
setJoinDirection((val.getJoinDirection() == val.JOIN_FORWARD)
setJoinDirection((val.getJoinDirection() == ValueMapping.JOIN_FORWARD)
? JOIN_FORWARD : JOIN_INVERSE);
}
syncForeignKey(val, val.getForeignKey(), local, foreign);
@ -337,14 +374,17 @@ public class ValueMappingInfo
/**
* Raw column data.
*/
public List getMapsIdColumns() {
return (_mapsIdCols == null) ? Collections.EMPTY_LIST : _mapsIdCols;
public List<Column> getMapsIdColumns() {
if (_mapsIdCols == null) {
return Collections.emptyList();
}
return _mapsIdCols;
}
/**
* Raw column data.
*/
public void setMapsIdColumns(List cols) {
public void setMapsIdColumns(List<Column> cols) {
_mapsIdCols = cols;
}
}

View File

@ -26,7 +26,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.meta.strats.NoneVersionStrategy;
import org.apache.openjpa.jdbc.meta.strats.SuperclassVersionStrategy;
import org.apache.openjpa.jdbc.schema.Column;
@ -69,21 +69,21 @@ public class VersionMappingInfo
public Column[] getMultiTableColumns(Version vers, Column[] templates,
boolean adapt) {
Table primaryTable = vers.getClassMapping().getTable();
List<String> secondaryTableNames = Arrays.asList(vers
.getClassMapping().getMappingInfo().getSecondaryTableNames());
List<DBIdentifier> secondaryTableNames = Arrays.asList(vers
.getClassMapping().getMappingInfo().getSecondaryTableIdentifiers());
Map<Table, List<Column>> assign = new LinkedHashMap<Table,
List<Column>>();
for (Column col : templates) {
String tableName = col.getTableName();
DBIdentifier tableName = col.getTableIdentifier();
Table table;
if (StringUtils.isEmpty(tableName)
|| tableName.equals(primaryTable.getName())) {
if (DBIdentifier.isEmpty(tableName)
|| tableName.equals(primaryTable.getIdentifier())) {
table = primaryTable;
} else if (secondaryTableNames.contains(tableName)) {
table = primaryTable.getSchema().getTable(tableName);
} else {
throw new UserException(_loc.get("bad-version-column-table",
col.getName(), tableName));
col.getIdentifier().toString(), tableName));
}
if (!assign.containsKey(table))
assign.put(table, new ArrayList<Column>());
@ -147,9 +147,9 @@ public class VersionMappingInfo
boolean spansMultipleTables(Column[] cols) {
if (cols == null || cols.length <= 1)
return false;
Set<String> tables = new HashSet<String>();
Set<DBIdentifier> tables = new HashSet<DBIdentifier>();
for (Column col : cols)
if (tables.add(col.getTableName()) && tables.size() > 1)
if (tables.add(col.getTableIdentifier()) && tables.size() > 1)
return true;
return false;
}
@ -159,10 +159,10 @@ public class VersionMappingInfo
*/
private Table getSingleTable(Version version, Column[] cols) {
if (cols == null || cols.length == 0
|| StringUtils.isEmpty(cols[0].getTableName()))
|| DBIdentifier.isEmpty(cols[0].getTableIdentifier()))
return version.getClassMapping().getTable();
return version.getClassMapping().getTable().getSchema()
.getTable(cols[0].getTableName());
.getTable(cols[0].getTableIdentifier());
}

View File

@ -18,9 +18,11 @@
*/
package org.apache.openjpa.jdbc.meta.strats;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.meta.ValueMapping;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.ColumnIO;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.meta.JavaTypes;
/**
@ -40,10 +42,20 @@ public class BlobValueHandler
return _instance;
}
/**
* @deprecated
*/
public Column[] map(ValueMapping vm, String name, ColumnIO io,
boolean adapt) {
DBDictionary dict = vm.getMappingRepository().getDBDictionary();
DBIdentifier colName = DBIdentifier.newColumn(name, dict != null ? dict.delimitAll() : false);
return map(vm, colName, io, adapt);
}
public Column[] map(ValueMapping vm, DBIdentifier name, ColumnIO io,
boolean adapt) {
Column col = new Column();
col.setName(name);
col.setIdentifier(name);
col.setJavaType(JavaTypes.OBJECT);
col.setSize(-1);
return new Column[]{ col };

View File

@ -18,11 +18,13 @@
*/
package org.apache.openjpa.jdbc.meta.strats;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.kernel.JDBCStore;
import org.apache.openjpa.jdbc.meta.JavaSQLTypes;
import org.apache.openjpa.jdbc.meta.ValueMapping;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.ColumnIO;
import org.apache.openjpa.jdbc.sql.DBDictionary;
/**
* Handler for byte array values.
@ -42,10 +44,20 @@ public class ByteArrayValueHandler
return _instance;
}
/**
* @deprecated
*/
public Column[] map(ValueMapping vm, String name, ColumnIO io,
boolean adapt) {
DBDictionary dict = vm.getMappingRepository().getDBDictionary();
DBIdentifier colName = DBIdentifier.newColumn(name, dict != null ? dict.delimitAll() : false);
return map(vm, colName, io, adapt);
}
public Column[] map(ValueMapping vm, DBIdentifier name, ColumnIO io,
boolean adapt) {
Column col = new Column();
col.setName(name);
col.setIdentifier(name);
col.setJavaType(JavaSQLTypes.BYTES);
col.setSize(-1);
return new Column[]{ col };

View File

@ -23,11 +23,13 @@ import java.io.CharArrayWriter;
import java.io.IOException;
import java.io.Reader;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.kernel.JDBCStore;
import org.apache.openjpa.jdbc.meta.JavaSQLTypes;
import org.apache.openjpa.jdbc.meta.ValueMapping;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.ColumnIO;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.jdbc.sql.Sized;
import org.apache.openjpa.util.StoreException;
@ -49,10 +51,20 @@ public class CharArrayStreamValueHandler
return _instance;
}
/**
* @deprecated
*/
public Column[] map(ValueMapping vm, String name, ColumnIO io,
boolean adapt) {
DBDictionary dict = vm.getMappingRepository().getDBDictionary();
DBIdentifier colName = DBIdentifier.newColumn(name, dict != null ? dict.delimitAll() : false);
return map(vm, colName, io, adapt);
}
public Column[] map(ValueMapping vm, DBIdentifier name, ColumnIO io,
boolean adapt) {
Column col = new Column();
col.setName(name);
col.setIdentifier(name);
col.setJavaType(JavaSQLTypes.CHAR_STREAM);
col.setSize(-1);
return new Column[]{ col };

View File

@ -18,10 +18,12 @@
*/
package org.apache.openjpa.jdbc.meta.strats;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.kernel.JDBCStore;
import org.apache.openjpa.jdbc.meta.ValueMapping;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.ColumnIO;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.meta.JavaTypes;
/**
@ -42,10 +44,20 @@ public class CharArrayValueHandler
return _instance;
}
/**
* @deprecated
*/
public Column[] map(ValueMapping vm, String name, ColumnIO io,
boolean adapt) {
DBDictionary dict = vm.getMappingRepository().getDBDictionary();
DBIdentifier colName = DBIdentifier.newColumn(name, dict != null ? dict.delimitAll() : false);
return map(vm, colName, io, adapt);
}
public Column[] map(ValueMapping vm, DBIdentifier name, ColumnIO io,
boolean adapt) {
Column col = new Column();
col.setName(name);
col.setIdentifier(name);
col.setJavaType(JavaTypes.STRING);
return new Column[]{ col };
}

View File

@ -18,9 +18,11 @@
*/
package org.apache.openjpa.jdbc.meta.strats;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.meta.ValueMapping;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.ColumnIO;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.meta.JavaTypes;
/**
@ -40,10 +42,20 @@ public class ClobValueHandler
return _instance;
}
/**
* @deprecated
*/
public Column[] map(ValueMapping vm, String name, ColumnIO io,
boolean adapt) {
DBDictionary dict = vm.getMappingRepository().getDBDictionary();
DBIdentifier colName = DBIdentifier.newColumn(name, dict != null ? dict.delimitAll() : false);
return map(vm, colName, io, adapt);
}
public Column[] map(ValueMapping vm, DBIdentifier name, ColumnIO io,
boolean adapt) {
Column col = new Column();
col.setName(name);
col.setIdentifier(name);
col.setJavaType(JavaTypes.STRING);
col.setSize(-1);
return new Column[]{ col };

View File

@ -23,6 +23,7 @@ import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.Comparator;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
import org.apache.openjpa.jdbc.kernel.JDBCStore;
import org.apache.openjpa.jdbc.meta.ClassMapping;
@ -31,6 +32,7 @@ import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.ColumnIO;
import org.apache.openjpa.jdbc.schema.ForeignKey;
import org.apache.openjpa.jdbc.schema.Index;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.jdbc.sql.Result;
import org.apache.openjpa.jdbc.sql.Row;
import org.apache.openjpa.jdbc.sql.RowManager;
@ -147,12 +149,12 @@ public abstract class ColumnVersionStrategy
for (int i = 0; i < info.getColumns().size(); i++) {
templates[i] = new Column();
Column infoColumn = (Column)info.getColumns().get(i);
templates[i].setTableName(infoColumn.getTableName());
templates[i].setTableIdentifier(infoColumn.getTableIdentifier());
templates[i].setType(infoColumn.getType());
templates[i].setSize(infoColumn.getSize());
templates[i].setDecimalDigits(infoColumn.getDecimalDigits());
templates[i].setJavaType(getJavaType(i));
templates[i].setName(infoColumn.getName());
templates[i].setIdentifier(infoColumn.getIdentifier());
}
Column[] cols = info.getColumns(vers, templates, adapt);
for (int i = 0; i < cols.length; i++)
@ -162,7 +164,9 @@ public abstract class ColumnVersionStrategy
} else {
Column tmplate = new Column();
tmplate.setJavaType(getJavaType());
tmplate.setName("versn");
DBDictionary dict = vers.getMappingRepository().getDBDictionary();
DBIdentifier versName = DBIdentifier.newColumn("versn", dict != null ? dict.delimitAll() : false);
tmplate.setIdentifier(versName);
Column[] cols = info.getColumns(vers, new Column[]{ tmplate },
adapt);

View File

@ -25,8 +25,10 @@ import org.apache.openjpa.lib.util.*;
import org.apache.openjpa.kernel.*;
import org.apache.openjpa.util.*;
import org.apache.openjpa.jdbc.meta.*;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.kernel.*;
import org.apache.openjpa.jdbc.schema.*;
import org.apache.openjpa.jdbc.sql.DBDictionary;
/**
* <p>Handler for embedded objects as elements of a collection or map. For
@ -50,7 +52,17 @@ public class ElementEmbedValueHandler
private int _nullIdx = -1;
private boolean _synthetic = false;
/**
* @deprecated
*/
public Column[] map(ValueMapping vm, String name, ColumnIO io,
boolean adapt) {
DBDictionary dict = vm.getMappingRepository().getDBDictionary();
DBIdentifier colName = DBIdentifier.newColumn(name, dict != null ? dict.delimitAll() : false);
return map(vm, colName, io, adapt);
}
public Column[] map(ValueMapping vm, DBIdentifier name, ColumnIO io,
boolean adapt) {
LinkedList cols = new LinkedList();
LinkedList args = new LinkedList();

View File

@ -23,6 +23,7 @@ import java.util.ArrayList;
import java.util.List;
import org.apache.openjpa.enhance.PersistenceCapable;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
import org.apache.openjpa.jdbc.kernel.JDBCStore;
import org.apache.openjpa.jdbc.meta.ClassMapping;
@ -33,6 +34,7 @@ import org.apache.openjpa.jdbc.meta.ValueMapping;
import org.apache.openjpa.jdbc.meta.ValueMappingImpl;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.ColumnIO;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.kernel.ObjectIdStateManager;
import org.apache.openjpa.kernel.OpenJPAStateManager;
import org.apache.openjpa.kernel.StateManagerImpl;
@ -53,8 +55,19 @@ public abstract class EmbedValueHandler
/**
* Maps embedded value and gathers columns and arguments into given lists.
* @deprecated
*/
protected void map(ValueMapping vm, String name, ColumnIO io,
boolean adapt, List cols, List args) {
DBDictionary dict = vm.getMappingRepository().getDBDictionary();
DBIdentifier colName = DBIdentifier.newColumn(name, dict != null ? dict.delimitAll() : false);
map(vm, colName, io, adapt, cols, args);
}
/**
* Maps embedded value and gathers columns and arguments into given lists.
*/
protected void map(ValueMapping vm, DBIdentifier name, ColumnIO io,
boolean adapt, List cols, List args) {
// have to resolve embedded value to collect its columns
vm.getEmbeddedMapping().resolve(vm.MODE_META | vm.MODE_MAPPING);

View File

@ -20,10 +20,12 @@ package org.apache.openjpa.jdbc.meta.strats;
import java.lang.reflect.Method;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.kernel.JDBCStore;
import org.apache.openjpa.jdbc.meta.ValueMapping;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.ColumnIO;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.meta.JavaTypes;
import org.apache.openjpa.util.MetaDataException;
@ -52,7 +54,17 @@ public class EnumValueHandler
_ordinal = ordinal;
}
/**
* @deprecated
*/
public Column[] map(ValueMapping vm, String name, ColumnIO io,
boolean adapt) {
DBDictionary dict = vm.getMappingRepository().getDBDictionary();
DBIdentifier colName = DBIdentifier.newColumn(name, dict != null ? dict.delimitAll() : false);
return map(vm, colName, io, adapt);
}
public Column[] map(ValueMapping vm, DBIdentifier name, ColumnIO io,
boolean adapt) {
// all enum classes have a static method called 'values()'
// that returns an array of all the enum values
@ -64,7 +76,7 @@ public class EnumValueHandler
}
Column col = new Column();
col.setName(name);
col.setIdentifier(name);
if (_ordinal)
col.setJavaType(JavaTypes.SHORT);
else {

View File

@ -18,6 +18,7 @@
*/
package org.apache.openjpa.jdbc.meta.strats;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.meta.ClassMapping;
import org.apache.openjpa.jdbc.meta.ClassMappingInfo;
import org.apache.openjpa.jdbc.schema.Table;
@ -49,9 +50,9 @@ public class FlatClassStrategy
ClassMappingInfo info = cls.getMappingInfo();
info.assertNoSchemaComponents(cls, true);
if (info.getTableName() != null) {
Table table = info.createTable(cls, null, info.getSchemaName(),
info.getTableName(), false);
if (!DBIdentifier.isNull(info.getTableIdentifier())) {
Table table = info.createTable(cls, null, info.getSchemaIdentifier(),
info.getTableIdentifier(), false);
if (table != sup.getTable())
throw new MetaDataException(_loc.get("flat-table", cls,
table.getFullName(), sup.getTable().getFullName()));

View File

@ -20,6 +20,7 @@ package org.apache.openjpa.jdbc.meta.strats;
import java.sql.SQLException;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
import org.apache.openjpa.jdbc.kernel.JDBCStore;
import org.apache.openjpa.jdbc.meta.ClassMapping;
@ -27,6 +28,7 @@ import org.apache.openjpa.jdbc.meta.ClassMappingInfo;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.PrimaryKey;
import org.apache.openjpa.jdbc.schema.Table;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.jdbc.sql.Row;
import org.apache.openjpa.jdbc.sql.RowManager;
import org.apache.openjpa.jdbc.sql.Select;
@ -74,7 +76,9 @@ public class FullClassStrategy
Column[] pkCols = null;
if (cls.getIdentityType() == cls.ID_DATASTORE) {
Column id = new Column();
id.setName("id");
DBDictionary dict = cls.getMappingRepository().getDBDictionary();
DBIdentifier idName = DBIdentifier.newColumn("id", dict != null ? dict.delimitAll() : false);
id.setIdentifier(idName);
id.setJavaType(JavaTypes.LONG);
id.setComment("datastore id");
if (cls.getIdentityStrategy() == ValueStrategies.AUTOASSIGN)
@ -90,10 +94,10 @@ public class FullClassStrategy
// add a primary key if we don't have one already
PrimaryKey pk = table.getPrimaryKey();
if (pk == null) {
String pkname = null;
DBIdentifier pkname = DBIdentifier.NULL;
if (adapt)
pkname = cls.getMappingRepository().getMappingDefaults().
getPrimaryKeyName(cls, table);
getPrimaryKeyIdentifier(cls, table);
pk = table.addPrimaryKey(pkname);
pk.setLogical(!adapt);
if (pkCols != null)

View File

@ -21,6 +21,7 @@ package org.apache.openjpa.jdbc.meta.strats;
import java.sql.*;
import java.util.*;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.kernel.*;
import org.apache.openjpa.jdbc.meta.*;
import org.apache.openjpa.jdbc.schema.*;
@ -110,8 +111,8 @@ public class HandlerHandlerMapTableFieldStrategy
_kio = new ColumnIO();
List columns = key.getValueInfo().getColumns();
DBDictionary dict = field.getMappingRepository().getDBDictionary();
String colName = dict.getValidColumnName("key", field.getTable());
_kcols = HandlerStrategies.map(key, colName, _kio, adapt);
DBIdentifier colName = dict.getValidColumnName(DBIdentifier.newColumn("key"), field.getTable());
_kcols = HandlerStrategies.map(key, colName.getName(), _kio, adapt);
_vio = new ColumnIO();
_vcols = HandlerStrategies.map(val, "value", _vio, adapt);

View File

@ -27,6 +27,7 @@ import org.apache.openjpa.kernel.*;
import org.apache.openjpa.util.*;
import org.apache.openjpa.enhance.PersistenceCapable;
import org.apache.openjpa.jdbc.meta.*;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.kernel.*;
import org.apache.openjpa.jdbc.schema.*;
import org.apache.openjpa.jdbc.sql.*;
@ -164,7 +165,7 @@ public class HandlerRelationMapTableFieldStrategy
_kio = new ColumnIO();
DBDictionary dict = field.getMappingRepository().getDBDictionary();
_kcols = HandlerStrategies.map(key,
dict.getValidColumnName("key", field.getTable()), _kio, adapt);
dict.getValidColumnName(DBIdentifier.newColumn("key"), field.getTable()).getName(), _kio, adapt);
field.mapPrimaryKey(adapt);
}

View File

@ -20,23 +20,23 @@ package org.apache.openjpa.jdbc.meta.strats;
import java.sql.SQLException;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
import org.apache.openjpa.jdbc.kernel.JDBCStore;
import org.apache.openjpa.jdbc.meta.ClassMapping;
import org.apache.openjpa.jdbc.meta.FieldMapping;
import org.apache.openjpa.jdbc.meta.RelationId;
import org.apache.openjpa.jdbc.meta.ValueHandler;
import org.apache.openjpa.jdbc.meta.ValueMapping;
import org.apache.openjpa.jdbc.meta.ValueMappingInfo;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.ColumnIO;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.jdbc.sql.Joins;
import org.apache.openjpa.jdbc.sql.Result;
import org.apache.openjpa.jdbc.sql.Row;
import org.apache.openjpa.kernel.OpenJPAStateManager;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.util.InvalidStateException;
import org.apache.openjpa.util.UserException;
/**
* Utility methods for strategies using value handlers.
@ -58,9 +58,11 @@ public class HandlerStrategies {
vinfo.assertNoJoin(vm, true);
vinfo.assertNoForeignKey(vm, !adapt);
Column[] cols = vm.getHandler().map(vm, name, io, adapt);
DBDictionary dict = vm.getMappingRepository().getDBDictionary();
DBIdentifier colName = DBIdentifier.newColumn(name, dict != null ? dict.delimitAll() : false);
Column[] cols = vm.getHandler().map(vm, colName.getName(), io, adapt);
if (cols.length > 0 && cols[0].getTable() == null) {
cols = vinfo.getColumns(vm, name, cols,
cols = vinfo.getColumns(vm, colName, cols,
vm.getFieldMapping().getTable(), adapt);
if (vinfo.isImplicitRelation())
for (int i = 0; i < cols.length; i++)
@ -77,7 +79,7 @@ public class HandlerStrategies {
}
}
}
vm.mapConstraints(name, adapt);
vm.mapConstraints(colName, adapt);
return cols;
}

View File

@ -18,12 +18,14 @@
*/
package org.apache.openjpa.jdbc.meta.strats;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.kernel.JDBCStore;
import org.apache.openjpa.jdbc.meta.FieldMapping;
import org.apache.openjpa.jdbc.meta.JavaSQLTypes;
import org.apache.openjpa.jdbc.meta.ValueMapping;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.ColumnIO;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.meta.JavaTypes;
/**
@ -44,10 +46,20 @@ public class ImmutableValueHandler
return _instance;
}
/**
* @deprecated
*/
public Column[] map(ValueMapping vm, String name, ColumnIO io,
boolean adapt) {
DBDictionary dict = vm.getMappingRepository().getDBDictionary();
DBIdentifier colName = DBIdentifier.newColumn(name, dict != null ? dict.delimitAll() : false);
return map(vm, colName, io, adapt);
}
public Column[] map(ValueMapping vm, DBIdentifier name, ColumnIO io,
boolean adapt) {
Column col = new Column();
col.setName(name);
col.setIdentifier(name);
if (vm.getTypeCode() == JavaTypes.DATE)
col.setJavaType(JavaSQLTypes.getDateTypeCode(vm.getType()));
else

View File

@ -20,11 +20,13 @@ package org.apache.openjpa.jdbc.meta.strats;
import java.sql.SQLException;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.kernel.JDBCStore;
import org.apache.openjpa.jdbc.meta.ClassMapping;
import org.apache.openjpa.jdbc.meta.DiscriminatorMappingInfo;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.Index;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.jdbc.sql.Joins;
import org.apache.openjpa.jdbc.sql.Result;
import org.apache.openjpa.jdbc.sql.Row;
@ -79,7 +81,9 @@ public abstract class InValueDiscriminatorStrategy
Column tmplate = new Column();
tmplate.setJavaType(getJavaType());
tmplate.setName("typ");
DBDictionary dict = cls.getMappingRepository().getDBDictionary();
DBIdentifier typName = DBIdentifier.newColumn("typ", dict != null ? dict.delimitAll() : false);
tmplate.setIdentifier(typName);
Column[] cols = info.getColumns(disc, new Column[]{ tmplate }, adapt);
disc.setColumns(cols);

View File

@ -23,11 +23,13 @@ import java.io.Reader;
import java.sql.SQLException;
import java.sql.Types;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
import org.apache.openjpa.jdbc.kernel.JDBCStore;
import org.apache.openjpa.jdbc.meta.FieldMapping;
import org.apache.openjpa.jdbc.meta.ValueMappingInfo;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.jdbc.sql.PostgresDictionary;
import org.apache.openjpa.jdbc.sql.Result;
import org.apache.openjpa.jdbc.sql.Row;
@ -58,19 +60,22 @@ public class LobFieldStrategy extends AbstractFieldStrategy {
ValueMappingInfo vinfo = field.getValueInfo();
vinfo.assertNoJoin(field, true);
vinfo.assertNoForeignKey(field, !adapt);
DBDictionary dict = field.getMappingRepository().getDBDictionary();
DBIdentifier fieldName = DBIdentifier.newColumn(field.getName(), dict != null ? dict.delimitAll() : false);
Column tmpCol = new Column();
tmpCol.setName(field.getName());
tmpCol.setIdentifier(fieldName);
tmpCol.setType(fieldType);
tmpCol.setJavaType(field.getTypeCode());
tmpCol.setSize(-1);
Column[] cols = vinfo.getColumns(field, field.getName(),
Column[] cols = vinfo.getColumns(field, fieldName,
new Column[]{ tmpCol }, field.getTable(), adapt);
field.setColumns(cols);
field.setColumnIO(vinfo.getColumnIO());
field.mapConstraints(field.getName(), adapt);
field.mapConstraints(fieldName, adapt);
field.mapPrimaryKey(adapt);
}

View File

@ -24,6 +24,7 @@ import java.util.Map;
import org.apache.openjpa.enhance.PersistenceCapable;
import org.apache.openjpa.enhance.ReflectingPersistenceCapable;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
import org.apache.openjpa.jdbc.kernel.JDBCStore;
import org.apache.openjpa.jdbc.meta.ClassMapping;
@ -241,7 +242,7 @@ public abstract class MapTableFieldStrategy
val.getValueInfo().setColumns(field.getValueInfo().getColumns());
if (val.getTypeMapping().isMapped()) {
ValueMappingInfo vinfo = val.getValueInfo();
ForeignKey fk = vinfo.getTypeJoin(val, null, false, adapt);
ForeignKey fk = vinfo.getTypeJoin(val, DBIdentifier.NULL, false, adapt);
val.setForeignKey(fk);
val.setColumnIO(vinfo.getColumnIO());
} else

View File

@ -23,7 +23,7 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
import org.apache.openjpa.jdbc.kernel.JDBCStore;
import org.apache.openjpa.jdbc.meta.JavaSQLTypes;
@ -87,17 +87,20 @@ abstract class MaxEmbeddedLobFieldStrategy
vinfo.assertNoJoin(field, true);
vinfo.assertNoForeignKey(field, !adapt);
DBDictionary dict = field.getMappingRepository().getDBDictionary();
DBIdentifier fieldName = DBIdentifier.newColumn(field.getName(), dict != null ? dict.delimitAll() : false);
// get value columns
Column tmpCol = new Column();
tmpCol.setName(field.getName());
tmpCol.setIdentifier(fieldName);
tmpCol.setJavaType(getExpectedJavaType());
tmpCol.setSize(-1);
Column[] cols = vinfo.getColumns(field, field.getName(),
Column[] cols = vinfo.getColumns(field, fieldName,
new Column[]{ tmpCol }, field.getTable(), adapt);
field.setColumns(cols);
field.setColumnIO(vinfo.getColumnIO());
field.mapConstraints(field.getName(), adapt);
field.mapConstraints(fieldName, adapt);
field.mapPrimaryKey(adapt);
}

View File

@ -22,12 +22,14 @@ import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.kernel.JDBCStore;
import org.apache.openjpa.jdbc.meta.ClassMapping;
import org.apache.openjpa.jdbc.meta.FieldMapping;
import org.apache.openjpa.jdbc.meta.ValueMapping;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.ColumnIO;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.kernel.ObjectIdStateManager;
import org.apache.openjpa.kernel.OpenJPAStateManager;
import org.apache.openjpa.util.InternalException;
@ -44,7 +46,17 @@ public class ObjectIdValueHandler
private Object[] _args = null;
/**
* @deprecated
*/
public Column[] map(ValueMapping vm, String name, ColumnIO io,
boolean adapt) {
DBDictionary dict = vm.getMappingRepository().getDBDictionary();
DBIdentifier colName = DBIdentifier.newColumn(name, dict != null ? dict.delimitAll() : false);
return map(vm, colName, io, adapt);
}
public Column[] map(ValueMapping vm, DBIdentifier name, ColumnIO io,
boolean adapt) {
List cols = new ArrayList();
List args = new ArrayList();
@ -85,7 +97,7 @@ public class ObjectIdValueHandler
private void setMapsIdCols(List cols, ClassMapping cm) {
for (int i = 0; i < cols.size(); i++) {
String refColName = ((Column)cols.get(i)).getTarget();
DBIdentifier refColName = ((Column)cols.get(i)).getTargetIdentifier();
FieldMapping fm = getReferenceField(cm, refColName);
if (fm != null) {
List colList1 = new ArrayList();
@ -104,7 +116,7 @@ public class ObjectIdValueHandler
}
for (int i = 0; i < cols.size(); i++) {
String refColName = ((Column)cols.get(i)).getTarget();
DBIdentifier refColName = ((Column)cols.get(i)).getTargetIdentifier();
if (isReferenceField(fm, refColName)) {
List colList1 = new ArrayList();
colList1.add(cols.get(i));
@ -114,7 +126,7 @@ public class ObjectIdValueHandler
}
}
private FieldMapping getReferenceField(ClassMapping cm, String refColName) {
private FieldMapping getReferenceField(ClassMapping cm, DBIdentifier refColName) {
FieldMapping[] fmds = cm.getFieldMappings();
for (int i = 0; i < fmds.length; i++) {
if (isReferenceField(fmds[i], refColName))
@ -123,13 +135,13 @@ public class ObjectIdValueHandler
return null;
}
private boolean isReferenceField(FieldMapping fm, String refColName) {
private boolean isReferenceField(FieldMapping fm, DBIdentifier refColName) {
List cols = fm.getValueInfo().getColumns();
if (cols.size() == 0) {
if (fm.getName().equals(refColName))
return true;
} else {
if (((Column)cols.get(0)).getName().equals(refColName))
if (((Column)cols.get(0)).getIdentifier().equals(refColName))
return true;
}
return false;

View File

@ -20,6 +20,7 @@ package org.apache.openjpa.jdbc.meta.strats;
import java.sql.SQLException;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
import org.apache.openjpa.jdbc.kernel.JDBCStore;
import org.apache.openjpa.jdbc.meta.Embeddable;
@ -29,6 +30,7 @@ import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.ColumnIO;
import org.apache.openjpa.jdbc.schema.ForeignKey;
import org.apache.openjpa.jdbc.schema.PrimaryKey;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.jdbc.sql.Joins;
import org.apache.openjpa.jdbc.sql.Result;
import org.apache.openjpa.jdbc.sql.Row;
@ -75,12 +77,15 @@ public class PrimitiveFieldStrategy
vinfo.assertNoJoin(field, true);
vinfo.assertNoForeignKey(field, !adapt);
// Determine whether to delimit the base field name
DBDictionary dict = field.getMappingRepository().getDBDictionary();
DBIdentifier fieldName = DBIdentifier.newColumn(field.getName(), dict != null ? dict.delimitAll() : false);
// get value columns
Column tmpCol = new Column();
tmpCol.setName(field.getName());
tmpCol.setIdentifier(fieldName);
tmpCol.setJavaType(field.getTypeCode());
Column[] cols = vinfo.getColumns(field, field.getName(),
Column[] cols = vinfo.getColumns(field, fieldName,
new Column[]{ tmpCol }, field.getTable(), adapt);
if (field.getValueStrategy() == ValueStrategies.AUTOASSIGN)
cols[0].setAutoAssigned(true);
@ -89,7 +94,7 @@ public class PrimitiveFieldStrategy
cols[i].setImplicitRelation(true);
field.setColumns(cols);
field.setColumnIO(vinfo.getColumnIO());
field.mapConstraints(field.getName(), adapt);
field.mapConstraints(fieldName, adapt);
// add primary key columns to table pk if logical
field.mapPrimaryKey(adapt);

View File

@ -28,9 +28,9 @@ import java.util.Set;
import org.apache.openjpa.enhance.PersistenceCapable;
import org.apache.openjpa.enhance.ReflectingPersistenceCapable;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
import org.apache.openjpa.jdbc.kernel.JDBCStore;
import org.apache.openjpa.jdbc.kernel.MixedLockManager;
import org.apache.openjpa.jdbc.meta.ClassMapping;
import org.apache.openjpa.jdbc.meta.Embeddable;
import org.apache.openjpa.jdbc.meta.FieldMapping;
@ -144,15 +144,15 @@ public class RelationFieldStrategy
// around an inverse key: check to see if we're mapped as a secondary
// table join but we're in the table of the related type, and if so
// switch our join mapping info to our value mapping info
String tableName = field.getMappingInfo().getTableName();
DBIdentifier tableName = field.getMappingInfo().getTableIdentifier();
Table table = field.getTypeMapping().getTable();
ValueMappingInfo vinfo = field.getValueInfo();
if (tableName != null && table != null
&& (tableName.equalsIgnoreCase(table.getName())
|| tableName.equalsIgnoreCase(table.getFullName()))) {
if (!DBIdentifier.isNull(tableName) && table != null
&& (tableName.equals(table.getIdentifier())
|| tableName.equals(table.getFullIdentifier()))) {
vinfo.setJoinDirection(MappingInfo.JOIN_INVERSE);
vinfo.setColumns(field.getMappingInfo().getColumns());
field.getMappingInfo().setTableName(null);
field.getMappingInfo().setTableIdentifier(DBIdentifier.NULL);
field.getMappingInfo().setColumns(null);
}
@ -981,7 +981,7 @@ public class RelationFieldStrategy
if (gfk != null)
tcol = gfk.getColumn(tcol);
if (tfk == null)
tfk = new ForeignKey(null, tcol.getTable());
tfk = new ForeignKey(DBIdentifier.NULL, tcol.getTable());
tfk.join(tcol, fk.getPrimaryKeyColumn(cols[i]));
}
return tfk;

View File

@ -27,6 +27,7 @@ import org.apache.openjpa.kernel.*;
import org.apache.openjpa.util.*;
import org.apache.openjpa.enhance.PersistenceCapable;
import org.apache.openjpa.jdbc.meta.*;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.kernel.*;
import org.apache.openjpa.jdbc.schema.*;
import org.apache.openjpa.jdbc.sql.*;
@ -201,14 +202,14 @@ public class RelationRelationMapTableFieldStrategy
throw new MetaDataException(_loc.get("not-relation", val));
FieldMapping mapped = field.getMappedByMapping();
DBDictionary dict = field.getMappingRepository().getDBDictionary();
String keyName = null;
DBIdentifier keyName = null;
if (field.isUni1ToMFK() || (!field.isBiMTo1JT() && mapped != null)) {
handleMappedByForeignKey(adapt);
keyName = dict.getValidColumnName("vkey", field.getTable());
keyName = dict.getValidColumnName(DBIdentifier.newColumn("vkey"), field.getTable());
} else if (field.isBiMTo1JT() || mapped == null) {
field.mapJoin(adapt, true);
mapTypeJoin(val, "value", adapt);
keyName = dict.getValidColumnName("key", field.getTable());
mapTypeJoin(val, DBIdentifier.newColumn("value"), adapt);
keyName = dict.getValidColumnName(DBIdentifier.newColumn("key"), field.getTable());
}
mapTypeJoin(key, keyName, adapt);
@ -218,7 +219,7 @@ public class RelationRelationMapTableFieldStrategy
/**
* Map the given value's join to its persistent type.
*/
private void mapTypeJoin(ValueMapping vm, String name, boolean adapt) {
private void mapTypeJoin(ValueMapping vm, DBIdentifier name, boolean adapt) {
if (vm.getTypeMapping().isMapped()) {
ValueMappingInfo vinfo = vm.getValueInfo();
ForeignKey fk = vinfo.getTypeJoin(vm, name, false, adapt);

View File

@ -20,6 +20,7 @@ package org.apache.openjpa.jdbc.meta.strats;
import java.util.List;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.kernel.JDBCStore;
import org.apache.openjpa.jdbc.meta.ClassMapping;
import org.apache.openjpa.jdbc.meta.FieldMapping;
@ -104,6 +105,11 @@ public class RelationStrategies {
*/
public static void mapRelationToUnmappedPC(ValueMapping vm,
String name, boolean adapt) {
mapRelationToUnmappedPC(vm, DBIdentifier.newColumn(name), adapt);
}
public static void mapRelationToUnmappedPC(ValueMapping vm,
DBIdentifier name, boolean adapt) {
if (vm.getTypeMapping().getIdentityType() == ClassMapping.ID_UNKNOWN)
throw new MetaDataException(_loc.get("rel-to-unknownid", vm));
@ -119,11 +125,11 @@ public class RelationStrategies {
* class relation.
*/
private static Column[] newUnmappedPCTemplateColumns(ValueMapping vm,
String name) {
DBIdentifier name) {
ClassMapping rel = vm.getTypeMapping();
if (rel.getIdentityType() == ClassMapping.ID_DATASTORE) {
Column col = new Column();
col.setName(name);
col.setIdentifier(name);
col.setJavaType(JavaTypes.LONG);
col.setRelationId(true);
return new Column[]{ col };
@ -134,11 +140,15 @@ public class RelationStrategies {
for (int i = 0; i < pks.length; i++) {
cols[i] = mapPrimaryKey(vm, pks[i]);
if (cols.length == 1)
cols[i].setName(name);
else if (cols[i].getName() == null)
cols[i].setName(name + "_" + pks[i].getName());
else
cols[i].setName(name + "_" + cols[i].getName());
cols[i].setIdentifier(name);
else if (DBIdentifier.isNull(cols[i].getIdentifier())) {
DBIdentifier sName = DBIdentifier.combine(cols[i].getIdentifier(), pks[i].getName());
cols[i].setIdentifier(sName);
}
else {
DBIdentifier sName = DBIdentifier.combine(cols[i].getIdentifier(), cols[i].getName());
cols[i].setIdentifier(sName);
}
cols[i].setTargetField(pks[i].getName());
cols[i].setRelationId(true);
}
@ -193,7 +203,7 @@ public class RelationStrategies {
}
if (tmplate != null) {
col.setName(tmplate.getName());
col.setIdentifier(tmplate.getIdentifier());
col.setType(tmplate.getType());
col.setTypeName(tmplate.getTypeName());
col.setSize(tmplate.getSize());

View File

@ -22,16 +22,19 @@ import java.sql.SQLException;
import java.util.BitSet;
import java.util.Collection;
import org.apache.openjpa.jdbc.identifier.Normalizer;
import org.apache.openjpa.jdbc.kernel.JDBCStore;
import org.apache.openjpa.jdbc.meta.ClassMapping;
import org.apache.openjpa.jdbc.meta.FieldMapping;
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.jdbc.sql.Row;
import org.apache.openjpa.jdbc.sql.RowImpl;
import org.apache.openjpa.jdbc.sql.RowManager;
import org.apache.openjpa.kernel.OpenJPAStateManager;
import org.apache.openjpa.kernel.StoreManager;
import org.apache.openjpa.lib.identifier.IdentifierConfiguration;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.util.ArrayStateImage;
import org.apache.openjpa.util.InternalException;
@ -238,7 +241,7 @@ public class StateComparisonVersionStrategy
* WHERE clause of an UPDATE to test whether the current database
* record matches our stored version.
*/
public String getSQL() {
public String getSQL(DBDictionary dict) {
Column[] cols = getTable().getColumns();
StringBuilder buf = new StringBuilder();
boolean hasWhere = false;
@ -251,9 +254,9 @@ public class StateComparisonVersionStrategy
if (hasWhere)
buf.append(" AND ");
if (val == NULL)
buf.append(cols[i]).append(" IS NULL");
buf.append(dict.getColumnDBName(cols[i]) + " IS NULL");
else
buf.append(cols[i]).append(" = ?");
buf.append(dict.getColumnDBName(cols[i]) + " = ?");
hasWhere = true;
}
return buf.toString();

View File

@ -20,6 +20,7 @@ package org.apache.openjpa.jdbc.meta.strats;
import java.sql.SQLException;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
import org.apache.openjpa.jdbc.kernel.JDBCStore;
import org.apache.openjpa.jdbc.meta.Embeddable;
@ -30,6 +31,7 @@ import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.ColumnIO;
import org.apache.openjpa.jdbc.schema.ForeignKey;
import org.apache.openjpa.jdbc.schema.PrimaryKey;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.jdbc.sql.Joins;
import org.apache.openjpa.jdbc.sql.Result;
import org.apache.openjpa.jdbc.sql.Row;
@ -71,19 +73,22 @@ public class StringFieldStrategy
vinfo.assertNoJoin(field, true);
vinfo.assertNoForeignKey(field, !adapt);
DBDictionary dict = field.getMappingRepository().getDBDictionary();
DBIdentifier fieldName = DBIdentifier.newColumn(field.getName(), dict != null ? dict.delimitAll() : false);
// get value columns
Column tmpCol = new Column();
tmpCol.setName(field.getName());
tmpCol.setIdentifier(fieldName);
tmpCol.setJavaType(field.getTypeCode());
Column[] cols = vinfo.getColumns(field, field.getName(),
Column[] cols = vinfo.getColumns(field, fieldName,
new Column[]{ tmpCol }, field.getTable(), adapt);
if (field.getValueStrategy() == ValueStrategies.AUTOASSIGN)
cols[0].setAutoAssigned(true);
field.setColumns(cols);
field.setColumnIO(vinfo.getColumnIO());
field.mapConstraints(field.getName(), adapt);
field.mapConstraints(fieldName, adapt);
// add primary key columns to table pk if logical
field.mapPrimaryKey(adapt);

View File

@ -21,12 +21,14 @@ package org.apache.openjpa.jdbc.meta.strats;
import java.sql.SQLException;
import org.apache.openjpa.enhance.PersistenceCapable;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
import org.apache.openjpa.jdbc.kernel.JDBCStore;
import org.apache.openjpa.jdbc.meta.RelationId;
import org.apache.openjpa.jdbc.meta.ValueMapping;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.ColumnIO;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.kernel.OpenJPAStateManager;
import org.apache.openjpa.kernel.StoreContext;
import org.apache.openjpa.lib.util.Localizer;
@ -56,10 +58,20 @@ public class UntypedPCValueHandler
return _instance;
}
/**
* @deprecated
*/
public Column[] map(ValueMapping vm, String name, ColumnIO io,
boolean adapt) {
DBDictionary dict = vm.getMappingRepository().getDBDictionary();
DBIdentifier colName = DBIdentifier.newColumn(name, dict != null ? dict.delimitAll() : false);
return map(vm, colName, io, adapt);
}
public Column[] map(ValueMapping vm, DBIdentifier name, ColumnIO io,
boolean adapt) {
Column col = new Column();
col.setName(name);
col.setIdentifier(name);
col.setJavaType(JavaTypes.STRING);
col.setRelationId(true);
return new Column[]{ col };

View File

@ -20,6 +20,7 @@ package org.apache.openjpa.jdbc.meta.strats;
import java.sql.SQLException;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
import org.apache.openjpa.jdbc.kernel.JDBCStore;
import org.apache.openjpa.jdbc.meta.ClassMapping;
@ -79,10 +80,10 @@ public class VerticalClassStrategy
// add a primary key if we don't have one already
PrimaryKey pk = table.getPrimaryKey();
if (pk == null) {
String pkname = null;
DBIdentifier pkname = DBIdentifier.NULL;
if (adapt)
pkname = cls.getMappingRepository().getMappingDefaults().
getPrimaryKeyName(cls, table);
getPrimaryKeyIdentifier(cls, table);
pk = table.addPrimaryKey(pkname);
pk.setLogical(!adapt);
pk.setColumns(pkCols);

View File

@ -28,10 +28,12 @@ import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.kernel.JDBCStore;
import org.apache.openjpa.jdbc.meta.ValueMapping;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.ColumnIO;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.meta.JavaTypes;
import org.apache.openjpa.util.InternalException;
@ -45,14 +47,24 @@ public class XMLValueHandler
extends AbstractValueHandler {
private static final String PROXY_SUFFIX = "$proxy";
/**
* @deprecated
*/
public Column[] map(ValueMapping vm, String name, ColumnIO io,
boolean adapt) {
DBDictionary dict = vm.getMappingRepository().getDBDictionary();
DBIdentifier colName = DBIdentifier.newColumn(name, dict != null ? dict.delimitAll() : false);
return map(vm, colName, io, adapt);
}
public Column[] map(ValueMapping vm, DBIdentifier name, ColumnIO io,
boolean adapt) {
Column col = new Column();
col.setName(name);
col.setIdentifier(name);
col.setJavaType(JavaTypes.STRING);
col.setSize(-1);
col.setTypeName(vm.getMappingRepository().getDBDictionary()
.xmlTypeName);
col.setTypeIdentifier(DBIdentifier.newColumnDefinition(vm.getMappingRepository().getDBDictionary()
.xmlTypeName));
col.setXML(true);
return new Column[]{ col };
}

View File

@ -27,6 +27,8 @@ import java.sql.Timestamp;
import java.sql.Types;
import org.apache.commons.lang.StringUtils;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.identifier.QualifiedDBIdentifier;
import org.apache.openjpa.jdbc.meta.JavaSQLTypes;
import org.apache.openjpa.jdbc.meta.VersionStrategy;
import org.apache.openjpa.meta.JavaTypes;
@ -39,6 +41,7 @@ import serp.util.Numbers;
* @author Abe White
* @author Stephen Kim
*/
@SuppressWarnings("serial")
public class Column
extends ReferenceCounter {
@ -50,13 +53,12 @@ public class Column
public static final int FLAG_FK_UPDATE = 2 << 5;
public static final int FLAG_PK_JOIN = 2 << 6;
private String _name = null;
private String _fullName = null;
private DBIdentifier _name = DBIdentifier.NULL;
private Table _table = null;
private String _tableName = null;
private String _schemaName = null;
private DBIdentifier _tableName = DBIdentifier.NULL;
private DBIdentifier _schemaName = DBIdentifier.NULL;
private int _type = Types.OTHER;
private String _typeName = null;
private DBIdentifier _typeName = DBIdentifier.NULL;
private int _javaType = JavaTypes.OBJECT;
private int _size = 0;
private int _decimals = 0;
@ -66,9 +68,10 @@ public class Column
private boolean _autoAssign = false;
private boolean _rel = false;
private boolean _implicitRelation = false;
private String _target = null;
private DBIdentifier _target = DBIdentifier.NULL;
private String _targetField = null;
private int _flags = 0;
private QualifiedDBIdentifier _fullPath = null;
private int _index = 0;
private boolean _pk = false;
@ -88,12 +91,17 @@ public class Column
*
* @param name the name of the column
* @param table the column's table
* @deprecated
*/
public Column(String name, Table table) {
setName(name);
this(DBIdentifier.newColumn(name), table);
}
public Column(DBIdentifier name, Table table) {
setIdentifier(name);
if (table != null) {
setTableName(table.getName());
setSchemaName(table.getSchemaName());
setTableIdentifier(table.getIdentifier());
setSchemaIdentifier(table.getSchemaIdentifier());
}
_table = table;
}
@ -169,79 +177,118 @@ public class Column
/**
* The column's table name.
* @deprecated
*/
public String getTableName() {
return _tableName;
return getTableIdentifier().getName();
}
public DBIdentifier getTableIdentifier() {
return _tableName == null ? DBIdentifier.NULL : _tableName;
}
/**
* The column's table name. You can only call this method on columns
* whose table object is not set.
* @deprecated
*/
public void setTableName(String name) {
if (getTable() != null)
throw new IllegalStateException();
_tableName = name;
_fullName = null;
setTableIdentifier(DBIdentifier.newTable(name));
}
public void setTableIdentifier(DBIdentifier name) {
if (getTable() != null)
throw new IllegalStateException();
_tableName = name == null ? DBIdentifier.NULL : name;
_fullPath = null;
}
/**
* Reset the table name with the fully qualified table name which
* includes the schema name
* @deprecated
*/
public void resetTableName(String name) {
_tableName = name;
_tableName = DBIdentifier.newTable(name);
}
public void resetTableIdentifier(DBIdentifier table) {
_tableName = table == null ? DBIdentifier.NULL : table;
}
/**
* The column's schema name.
* @deprecated
*/
public String getSchemaName() {
return _schemaName;
return getSchemaIdentifier().getName();
}
public DBIdentifier getSchemaIdentifier() {
return _schemaName == null ? DBIdentifier.NULL : _schemaName;
}
/**
* The column's schema name. You can only call this method on columns
* whose table object is not set.
* @deprecated use setSchemaIdentifier(DBIdentifier name)
*/
public void setSchemaName(String name) {
setSchemaIdentifier(DBIdentifier.newSchema(name));
}
public void setSchemaIdentifier(DBIdentifier name) {
if (getTable() != null)
throw new IllegalStateException();
_schemaName = name;
_schemaName = name == null ? DBIdentifier.NULL : name;
}
/**
* Return the column's name.
* @deprecated use getIdentifier()
*/
public String getName() {
return _name;
return getIdentifier().getName();
}
public DBIdentifier getIdentifier() {
return _name == null ? DBIdentifier.NULL : _name;
}
/**
* Set the column's name. You can only call this method on columns
* whose table object is not set.
* @deprecated use setIdentifier(DBIdentifier name)
*/
public void setName(String name) {
setIdentifier(DBIdentifier.newColumn(name));
}
public void setIdentifier(DBIdentifier name) {
if (getTable() != null)
throw new IllegalStateException();
_name = name;
_fullName = null;
_name = name == null ? DBIdentifier.NULL : name;
_fullPath = null;
}
/**
* Return the column's full name, in the form &lt;table&gt;.&lt;name&gt;.
* @deprecated use getFullDBIdentifier()
*/
public String getFullName() {
if (_fullName == null) {
String name = getName();
if (name == null)
return null;
String tname = getTableName();
if (tname == null)
return name;
_fullName = tname + "." + name;
return getFullDBIdentifier().getName();
}
public DBIdentifier getFullDBIdentifier() {
return getQualifiedPath().getIdentifier();
}
public QualifiedDBIdentifier getQualifiedPath() {
if (_fullPath == null) {
_fullPath = QualifiedDBIdentifier.newPath(getTableIdentifier(), getIdentifier() );
}
return _fullName;
return _fullPath;
}
/**
@ -262,16 +309,26 @@ public class Column
/**
* The database-specific SQL type of this column.
* @deprecated
*/
public String getTypeName() {
return _typeName;
return getTypeIdentifier().getName();
}
public DBIdentifier getTypeIdentifier() {
return _typeName == null ? DBIdentifier.NULL : _typeName ;
}
/**
* The database-specific SQL type of this column.
* @deprecated
*/
public void setTypeName(String typeName) {
_typeName = typeName;
setTypeIdentifier(DBIdentifier.newColumnDefinition(typeName));
}
public void setTypeIdentifier(DBIdentifier typeName) {
_typeName = typeName == null ? DBIdentifier.NULL : typeName;
}
/**
@ -470,16 +527,26 @@ public class Column
/**
* The name of the column this column joins to, if any. Used for mapping.
* @deprecated use getTargetIdentifier()
*/
public String getTarget() {
return _target;
return getTargetIdentifier().getName();
}
public DBIdentifier getTargetIdentifier() {
return _target == null ? DBIdentifier.NULL : _target;
}
/**
* The name of the column this column joins to, if any. Used for mapping.
* @deprecated use setTargetIdentifier(DBIdentifier target)
*/
public void setTarget(String target) {
_target = StringUtils.trimToNull(target);
setTargetIdentifier(DBIdentifier.newColumn(StringUtils.trimToNull(target)));
}
public void setTargetIdentifier(DBIdentifier target) {
_target = target == null ? DBIdentifier.NULL : DBIdentifier.trimToNull(target);
}
/**
@ -661,7 +728,7 @@ public class Column
* Returns the column name.
*/
public String toString() {
return getName();
return getIdentifier().getName();
}
/**
@ -687,9 +754,9 @@ public class Column
if (col == null)
return false;
if (!getFullName().equalsIgnoreCase(col.getFullName()))
if (!getQualifiedPath().equals(col.getQualifiedPath()))
return false;
if (!isCompatible(col.getType(), col.getTypeName(), col.getSize(),
if (!isCompatible(col.getType(), col.getTypeIdentifier().getName(), col.getSize(),
col.getDecimalDigits()))
return false;
if (getType() == Types.VARCHAR && getSize() > 0 && col.getSize() > 0
@ -704,12 +771,12 @@ public class Column
public void copy(Column from) {
if (from == null)
return;
if (getName() == null)
setName(from.getName());
if (DBIdentifier.isNull(getIdentifier()))
setIdentifier(from.getIdentifier());
if (getType() == Types.OTHER)
setType(from.getType());
if (getTypeName() == null)
setTypeName(from.getTypeName());
if (DBIdentifier.isNull(getTypeIdentifier()))
setTypeIdentifier(from.getTypeIdentifier());
if (getJavaType() == JavaTypes.OBJECT)
setJavaType(from.getJavaType());
if (getSize() == 0)
@ -726,8 +793,8 @@ public class Column
setRelationId(from.isRelationId());
if (!isImplicitRelation())
setImplicitRelation(from.isRelationId());
if (getTarget() == null)
setTarget(from.getTarget());
if (DBIdentifier.isNull(getTargetIdentifier()))
setTargetIdentifier(from.getTargetIdentifier());
if (getTargetField() == null)
setTargetField(from.getTargetField());
if (_flags == 0)
@ -761,7 +828,7 @@ public class Column
}
public boolean hasComment() {
return _comment != null && !_comment.equalsIgnoreCase(_name);
return _comment != null && !_comment.equalsIgnoreCase(_name.toString());
}
public String getComment() {

View File

@ -27,6 +27,7 @@ import java.io.Serializable;
*
* @author Abe White
*/
@SuppressWarnings("serial")
public class ColumnIO
implements Serializable {

View File

@ -18,21 +18,25 @@
*/
package org.apache.openjpa.jdbc.schema;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.identifier.QualifiedDBIdentifier;
/**
* A table constraint. This class is closely aligned with the constraint
* information available from {@link java.sql.DatabaseMetaData}.
*
* @author Abe White
*/
@SuppressWarnings("serial")
public abstract class Constraint
extends ReferenceCounter {
private String _name = null;
private String _fullName = null;
private DBIdentifier _name = DBIdentifier.NULL;
private QualifiedDBIdentifier _fullPath = null;
private Table _table = null;
private String _tableName = null;
private String _schemaName = null;
private String _columnName = null;
private DBIdentifier _tableName = DBIdentifier.NULL;
private DBIdentifier _schemaName = DBIdentifier.NULL;
private DBIdentifier _columnName = DBIdentifier.NULL;
private boolean _deferred = false;
/**
@ -46,12 +50,17 @@ public abstract class Constraint
*
* @param name the name of the constraint, or null if none
* @param table the local table of the constraint
* @deprecated
*/
Constraint(String name, Table table) {
setName(name);
this(DBIdentifier.newConstant(name), table);
}
Constraint(DBIdentifier name, Table table) {
setIdentifier(name);
if (table != null) {
setTableName(table.getName());
setSchemaName(table.getSchemaName());
setTableIdentifier(table.getIdentifier());
setSchemaIdentifier(table.getSchemaIdentifier());
}
_table = table;
}
@ -73,34 +82,55 @@ public abstract class Constraint
/**
* Return the column's table name.
* @deprecated
*/
public String getTableName() {
return _tableName;
return getTableIdentifier().getName();
}
public DBIdentifier getTableIdentifier() {
return _tableName == null ? DBIdentifier.NULL : _tableName;
}
/**
* Set the column's table name. You can only call this method on
* columns whose table object is not set.
* @deprecated
*/
public void setTableName(String name) {
if (getTable() != null)
throw new IllegalStateException();
_tableName = name;
_fullName = null;
setTableIdentifier(DBIdentifier.newTable(name));
}
public void setTableIdentifier(DBIdentifier name) {
if (getTable() != null)
throw new IllegalStateException();
_tableName = name;
_fullPath = null;
}
/**
* Return the column table's schema name.
* @deprecated
*/
public String getSchemaName() {
return _schemaName;
return getSchemaIdentifier().getName();
}
public DBIdentifier getSchemaIdentifier() {
return _schemaName == null ? DBIdentifier.NULL : _schemaName;
}
/**
* Set the column table's schema name. You can only call this method on
* columns whose tbale object is not set.
* columns whose table object is not set.
* @deprecated
*/
public void setSchemaName(String schema) {
setSchemaIdentifier(DBIdentifier.newSchema(schema));
}
public void setSchemaIdentifier(DBIdentifier schema) {
if (getTable() != null)
throw new IllegalStateException();
_schemaName = schema;
@ -108,16 +138,26 @@ public abstract class Constraint
/**
* Return the column's name.
* @deprecated
*/
public String getColumnName() {
return _columnName;
return getColumnIdentifier().getName();
}
public DBIdentifier getColumnIdentifier() {
return _columnName == null ? DBIdentifier.NULL : _columnName;
}
/**
* Set the column's name. You can only call this method on
* columns whose table object is not set.
* @deprecated
*/
public void setColumnName(String name) {
setColumnIdentifier(DBIdentifier.newColumn(name));
}
public void setColumnIdentifier(DBIdentifier name) {
if (getTable() != null)
throw new IllegalStateException();
_columnName = name;
@ -125,38 +165,53 @@ public abstract class Constraint
/**
* Return the name of the constraint.
* @deprecated
*/
public String getName() {
return _name;
return getIdentifier().getName();
}
public DBIdentifier getIdentifier() {
return _name == null ? DBIdentifier.NULL : _name;
}
/**
* Set the name of the constraint. This method cannot be called if the
* constraint already belongs to a table.
* @deprecated
*/
public void setName(String name) {
setIdentifier(DBIdentifier.newConstraint(name));
}
public void setIdentifier(DBIdentifier name) {
if (getTable() != null)
throw new IllegalStateException();
_name = name;
_fullName = null;
_fullPath = null;
}
/**
* Return the full name of the constraint.
* @deprecated
*/
public String getFullName() {
if (_fullName == null) {
String name = getName();
if (name == null)
return null;
String tname = getTableName();
if (tname == null)
return name;
_fullName = tname + "." + name;
}
return _fullName;
return getFullIdentifier().getName();
}
public QualifiedDBIdentifier getQualifiedPath() {
if (_fullPath == null) {
_fullPath = QualifiedDBIdentifier.newPath(getTableIdentifier(), getIdentifier());
}
return _fullPath;
}
public DBIdentifier getFullIdentifier() {
return getQualifiedPath().getIdentifier();
}
/**
* Return whether this constraint is a logical constraint only; i.e.
* if it does not exist in the database.
@ -178,8 +233,8 @@ public abstract class Constraint
}
public String toString() {
if (getName() != null)
return getName();
if (!getIdentifier().isNull())
return getIdentifier().getName();
String name = getClass().getName();
name = name.substring(name.lastIndexOf('.') + 1);

View File

@ -21,6 +21,9 @@ package org.apache.openjpa.jdbc.schema;
import java.sql.Types;
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
import org.apache.openjpa.jdbc.identifier.Normalizer;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.identifier.QualifiedDBIdentifier;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.lib.conf.Configurable;
import org.apache.openjpa.lib.conf.Configuration;
@ -34,17 +37,18 @@ import org.apache.openjpa.lib.conf.Configuration;
*
* @author Abe White
*/
@SuppressWarnings("serial")
public class DynamicSchemaFactory
extends SchemaGroup
implements SchemaFactory, Configurable {
private transient DBDictionary _dict = null;
private String _schema = null;
private DBIdentifier _schema = DBIdentifier.NULL;
public void setConfiguration(Configuration conf) {
JDBCConfiguration jconf = (JDBCConfiguration) conf;
_dict = jconf.getDBDictionaryInstance();
_schema = jconf.getSchema();
_schema = DBIdentifier.newSchema(jconf.getSchema());
}
public void startConfiguration() {
@ -69,45 +73,67 @@ public class DynamicSchemaFactory
return super.findTable(name) != null;
}
public boolean isKnownTable(QualifiedDBIdentifier path) {
return super.findTable(path) != null;
}
public Table findTable(String name) {
return super.findTable(name);
}
public Table findTable(DBIdentifier name) {
if (name == null)
return null;
Table table = super.findTable(name);
QualifiedDBIdentifier path = QualifiedDBIdentifier.getPath(name);
return findTable(path);
}
public Table findTable(QualifiedDBIdentifier path) {
if (DBIdentifier.isNull(path))
return null;
Table table = super.findTable(path);
if (table != null)
return table;
// if full name, split
String schemaName = null;
String tableName = name;
int dotIdx = name.lastIndexOf('.');
if (dotIdx != -1) {
schemaName = name.substring(0, dotIdx);
tableName = name.substring(dotIdx + 1);
} else
DBIdentifier schemaName = DBIdentifier.NULL;
DBIdentifier tableName = path.getUnqualifiedName();
if (!DBIdentifier.isNull(path.getSchemaName())) {
schemaName = path.getSchemaName();
} else {
schemaName = _schema;
}
Schema schema = getSchema(schemaName);
if (schema == null) {
schema = addSchema(schemaName);
// TODO: temp until a more global name scheme is implemented
addDelimSchemaName(_dict.addDelimiters(schemaName), schema);
}
// Ensure only valid table name(s) are added to the schema
if (tableName.length() > _dict.maxTableNameLength) {
if (tableName.getName().length() > _dict.maxTableNameLength) {
return schema.addTable(tableName,
_dict.getValidTableName(tableName, getSchema(schemaName)));
}
return schema.addTable(tableName);
}
// protected Table newTable(String name, Schema schema) {
// return new DynamicTable(name, schema);
// }
protected Table newTable(String name, Schema schema) {
protected Table newTable(DBIdentifier name, Schema schema) {
return new DynamicTable(name, schema);
}
protected Column newColumn(String name, Table table) {
// protected Column newColumn(String name, Table table) {
// return new DynamicColumn(name, table);
// }
protected Column newColumn(DBIdentifier name, Table table) {
return new DynamicColumn(name, table);
}
@ -121,21 +147,42 @@ public class DynamicSchemaFactory
super(name, schema);
}
public DynamicTable(DBIdentifier name, Schema schema) {
super(name, schema);
}
/**
* @deprecated
*/
public Column getColumn(String name) {
return getColumn(name, null);
}
public Column getColumn(DBIdentifier name) {
return getColumn(name, null);
}
/**
* @deprecated
*/
public Column getColumn(String name, DBDictionary dict) {
if (name == null)
return null;
return getColumn(DBIdentifier.newColumn(name), dict);
}
Column col = super.getColumn(name, dict);
public Column getColumn(DBIdentifier name, DBDictionary dict) {
if (DBIdentifier.isNull(name))
return null;
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) ||
_dict.getInvalidColumnWordSet().contains(name.toUpperCase())) {
if ((name.getName().length() > _dict.maxColumnNameLength) ||
_dict.getInvalidColumnWordSet().contains(
DBIdentifier.toUpper(name).getName())) {
return addColumn(name,
_dict.getValidColumnName(name, this));
}
@ -150,10 +197,17 @@ public class DynamicSchemaFactory
private class DynamicColumn
extends Column {
/**
* @deprecated
*/
public DynamicColumn(String name, Table table) {
super(name, table);
}
public DynamicColumn(DBIdentifier name, Table table) {
super(name, table);
}
public boolean isCompatible(int type, String typeName, int size,
int decimals) {
if (getType() != Types.OTHER)
@ -164,7 +218,7 @@ public class DynamicSchemaFactory
setType(type);
setSize(size);
if (typeName != null)
setTypeName(typeName);
setTypeIdentifier(DBIdentifier.newColumnDefinition(typeName));
if (decimals >= 0)
setDecimalDigits(decimals);
return true;

View File

@ -27,6 +27,8 @@ import java.util.List;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.openjpa.jdbc.identifier.Normalizer;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.lib.log.Log;
import org.apache.openjpa.lib.util.Localizer;
@ -40,6 +42,7 @@ import org.apache.openjpa.util.InvalidStateException;
*
* @author Abe White
*/
@SuppressWarnings("serial")
public class ForeignKey
extends Constraint {
@ -75,9 +78,9 @@ public class ForeignKey
private static final Localizer _loc =
Localizer.forPackage(ForeignKey.class);
private String _pkTableName = null;
private String _pkSchemaName = null;
private String _pkColumnName = null;
private DBIdentifier _pkTableName = DBIdentifier.NULL;
private DBIdentifier _pkSchemaName = DBIdentifier.NULL;
private DBIdentifier _pkColumnName = DBIdentifier.NULL;
private int _seq = 0;
private LinkedHashMap _joins = null;
@ -160,11 +163,16 @@ public class ForeignKey
*
* @param name the foreign key name, if any
* @param table the local table of the foreign key
* @deprecated
*/
public ForeignKey(String name, Table table) {
super(name, table);
}
public ForeignKey(DBIdentifier name, Table table) {
super(name, table);
}
public boolean isLogical() {
return _delAction == ACTION_NONE;
}
@ -227,19 +235,29 @@ public class ForeignKey
/**
* The name of the primary key table.
* @deprecated
*/
public String getPrimaryKeyTableName() {
return getPrimaryKeyTableIdentifier().getName();
}
public DBIdentifier getPrimaryKeyTableIdentifier() {
Table table = getPrimaryKeyTable();
if (table != null)
return table.getName();
return _pkTableName;
return table.getIdentifier();
return _pkTableName == null ? DBIdentifier.NULL : _pkTableName;
}
/**
* The name of the primary key table. You can only set the primary
* key table name on foreign keys that have not already been joined.
* @deprecated
*/
public void setPrimaryKeyTableName(String pkTableName) {
setPrimaryKeyTableIdentifier(DBIdentifier.newTable(pkTableName));
}
public void setPrimaryKeyTableIdentifier(DBIdentifier pkTableName) {
if (getPrimaryKeyTable() != null)
throw new IllegalStateException();
_pkTableName = pkTableName;
@ -247,11 +265,16 @@ public class ForeignKey
/**
* The name of the primary key table's schema.
* @deprecated
*/
public String getPrimaryKeySchemaName() {
return getPrimaryKeySchemaIdentifier().getName();
}
public DBIdentifier getPrimaryKeySchemaIdentifier() {
Table table = getPrimaryKeyTable();
if (table != null)
return table.getSchemaName();
return table.getSchemaIdentifier();
return _pkSchemaName;
}
@ -259,8 +282,13 @@ public class ForeignKey
* The name of the primary key table's schema. You can only set the
* primary key schema name on foreign keys that have not already been
* joined.
* @deprecated
*/
public void setPrimaryKeySchemaName(String pkSchemaName) {
setPrimaryKeySchemaIdentifier(DBIdentifier.newSchema(pkSchemaName));
}
public void setPrimaryKeySchemaIdentifier(DBIdentifier pkSchemaName) {
if (getPrimaryKeyTable() != null)
throw new IllegalStateException();
_pkSchemaName = pkSchemaName;
@ -268,17 +296,27 @@ public class ForeignKey
/**
* The name of the primary key column.
* @deprecated
*/
public String getPrimaryKeyColumnName() {
return _pkColumnName;
return getPrimaryKeyColumnIdentifier().getName();
}
public DBIdentifier getPrimaryKeyColumnIdentifier() {
return _pkColumnName == null ? DBIdentifier.NULL : _pkColumnName;
}
/**
* The name of the primary key column. You can only set the
* primary key column name on foreign keys that have not already been
* joined.
* @deprecated
*/
public void setPrimaryKeyColumnName(String pkColumnName) {
setPrimaryKeyColumnIdentifier(DBIdentifier.newColumn(pkColumnName));
}
public void setPrimaryKeyColumnIdentifier(DBIdentifier pkColumnName) {
if (getPrimaryKeyTable() != null)
throw new IllegalStateException();
_pkColumnName = pkColumnName;
@ -729,7 +767,7 @@ public class ForeignKey
private static boolean hasColumn(Column[] cols, Column col) {
for (int i = 0; i < cols.length; i++)
if (cols[i].getFullName().equalsIgnoreCase(col.getFullName()))
if (cols[i].getQualifiedPath().equals(col.getQualifiedPath()))
return true;
return false;
}
@ -745,36 +783,41 @@ public class ForeignKey
/**
* Return the name of the foreignkey constraint as defined in the database.
* @deprecated
*/
public String loadNameFromDB(DBDictionary dbdict, Connection conn) {
return loadIdentifierFromDB(dbdict, conn).getName();
}
public DBIdentifier loadIdentifierFromDB(DBDictionary dbdict, Connection conn) {
if( isLogical() || getTable() == null)
return null;
String retVal = null;
return DBIdentifier.NULL;
DBIdentifier retVal = DBIdentifier.NULL;
try{
Schema schema = getTable().getSchema();
ForeignKey[] fks = dbdict.getImportedKeys(conn.getMetaData(),
conn.getCatalog(), schema.getName(),
getTable().getName(), conn, false);
DBIdentifier.newCatalog(conn.getCatalog()), schema.getIdentifier(),
getTable().getIdentifier(), conn, false);
for ( int i=0; i< fks.length; i++) {
Table localtable = schema.getTable(fks[i].getTableName());
Table localtable = schema.getTable(fks[i].getTableIdentifier());
Table pkTable = schema.getTable(
fks[i].getPrimaryKeyTableName());
fks[i].getPrimaryKeyTableIdentifier());
boolean addFK = false;
ForeignKey fkTemp = localtable.getForeignKey(
fks[i].getName());
fks[i].getIdentifier());
if( fkTemp == null) {
addFK=true;
fkTemp = localtable.addForeignKey(
fks[i].getName());
fks[i].getIdentifier());
fkTemp.setDeferred(fks[i].isDeferred());
fkTemp.setDeleteAction(fks[i].getDeleteAction());
}
if (fks[i].getColumns() == null || fks[i].getColumns().length == 0) {
// Singular column foreign key
if( ! fkTemp.containsColumn(
localtable.getColumn(fks[i].getColumnName(), dbdict)))
fkTemp.join(localtable.getColumn(fks[i].getColumnName(), dbdict),
pkTable.getColumn(fks[i].getPrimaryKeyColumnName(), dbdict));
localtable.getColumn(fks[i].getColumnIdentifier())))
fkTemp.join(localtable.getColumn(fks[i].getColumnIdentifier()),
pkTable.getColumn(fks[i].getPrimaryKeyColumnIdentifier()));
} else {
// Add the multi-column foreign key, joining local and pk columns in
// the temporary key
@ -790,9 +833,9 @@ public class ForeignKey
}
for (int j = 0; j < locCols.length; j++) {
if( ! fkTemp.containsColumn(
localtable.getColumn(locCols[j].getName(), dbdict))) {
fkTemp.join(localtable.getColumn(locCols[j].getName(), dbdict),
pkTable.getColumn(pkCols[j].getName(), dbdict));
localtable.getColumn(locCols[j].getIdentifier()))) {
fkTemp.join(localtable.getColumn(locCols[j].getIdentifier()),
pkTable.getColumn(pkCols[j].getIdentifier()));
}
}
}
@ -800,7 +843,7 @@ public class ForeignKey
{
if(addFK)
localtable.removeForeignKey(fkTemp);
retVal = fks[i].getName();
retVal = fks[i].getIdentifier();
break;
}
if(addFK)
@ -825,8 +868,8 @@ public class ForeignKey
// If this FK is single column key, covert to a multi-column key
Column[] keyCols = createKeyColumns(this);
if (keyCols[0] != null && keyCols[1] != null) {
setPrimaryKeyColumnName(null);
setColumnName(null);
setPrimaryKeyColumnIdentifier(DBIdentifier.NULL);
setColumnIdentifier(DBIdentifier.NULL);
join(keyCols[0], keyCols[1]);
}
}
@ -845,19 +888,19 @@ public class ForeignKey
*/
private static Column[] createKeyColumns(ForeignKey fk) {
Column fkCol = null;
if (!StringUtils.isEmpty(fk.getColumnName())) {
if (!DBIdentifier.isEmpty(fk.getColumnIdentifier())) {
fkCol = new Column();
fkCol.setName(fk.getColumnName());
fkCol.setTableName(fk.getTableName());
fkCol.setSchemaName(fk.getSchemaName());
fkCol.setIdentifier(fk.getColumnIdentifier());
fkCol.setTableIdentifier(fk.getTableIdentifier());
fkCol.setSchemaIdentifier(fk.getSchemaIdentifier());
}
Column pkCol = null;
if (!StringUtils.isEmpty(fk.getPrimaryKeyColumnName())) {
if (!DBIdentifier.isEmpty(fk.getPrimaryKeyColumnIdentifier())) {
pkCol = new Column();
pkCol.setName(fk.getPrimaryKeyColumnName());
pkCol.setTableName(fk.getPrimaryKeyTableName());
pkCol.setSchemaName(fk.getPrimaryKeySchemaName());
pkCol.setIdentifier(fk.getPrimaryKeyColumnIdentifier());
pkCol.setTableIdentifier(fk.getPrimaryKeyTableIdentifier());
pkCol.setSchemaIdentifier(fk.getPrimaryKeySchemaIdentifier());
}
return new Column[] { fkCol, pkCol };
}
@ -878,7 +921,7 @@ public class ForeignKey
}
public int hashCode() {
return getFk().getName() != null ? getFk().getName().hashCode() : getFk().hashCode();
return getFk().getIdentifier() != null ? getFk().getIdentifier().hashCode() : getFk().hashCode();
}
public boolean equals(Object fkObj) {
@ -893,14 +936,14 @@ public class ForeignKey
return false;
if (getFk().isDeferred() != fk.isDeferred())
return false;
if (!getFk().getName().equals(fk.getName())) {
if (!getFk().getIdentifier().equals(fk.getIdentifier())) {
return false;
}
// Assert PK table name and schema
if (!StringUtils.equals(getFk().getPrimaryKeySchemaName(), fk.getPrimaryKeySchemaName()) ||
!StringUtils.equals(getFk().getPrimaryKeyTableName(), fk.getPrimaryKeyTableName()) ||
!StringUtils.equals(getFk().getSchemaName(), fk.getSchemaName()) ||
!StringUtils.equals(getFk().getTableName(), fk.getTableName())) {
if (!getFk().getPrimaryKeySchemaIdentifier().equals(fk.getPrimaryKeySchemaIdentifier()) ||
!getFk().getPrimaryKeyTableIdentifier().equals(fk.getPrimaryKeyTableIdentifier()) ||
!getFk().getSchemaIdentifier().equals(fk.getSchemaIdentifier()) ||
!getFk().getTableIdentifier().equals(fk.getTableIdentifier())) {
return false;
}
return true;

View File

@ -18,7 +18,7 @@
*/
package org.apache.openjpa.jdbc.schema;
import org.apache.commons.lang.StringUtils;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
/**
* Represents a database index. Can also represent a partial index,
@ -27,6 +27,7 @@ import org.apache.commons.lang.StringUtils;
* @author Abe White
* @author Stephen Kim
*/
@SuppressWarnings("serial")
public class Index
extends LocalConstraint {
@ -43,11 +44,16 @@ public class Index
*
* @param name the name of the index
* @param table the table of the index
* @deprecated
*/
public Index(String name, Table table) {
super(name, table);
}
public Index(DBIdentifier name, Table table) {
super(name, table);
}
/**
* Return true if this is a UNIQUE index.
*/
@ -66,6 +72,17 @@ public class Index
return false;
}
/**
* @deprecated
*/
public String getFullName() {
return getFullIdentifier().getName();
}
public DBIdentifier getFullIdentifier() {
return getQualifiedPath().getIdentifier();
}
/**
* Indexes are equal if they have the same name, the same columns, and
* are both unique/not unique.
@ -78,7 +95,7 @@ public class Index
if (isUnique() != idx.isUnique())
return false;
if (!StringUtils.equalsIgnoreCase(getFullName(), idx.getFullName()))
if (!getQualifiedPath().equals(idx.getQualifiedPath()))
return false;
return equalsLocalConstraint(idx);
}

View File

@ -23,9 +23,13 @@ import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.identifier.DBIdentifierUtil;
import org.apache.openjpa.jdbc.identifier.QualifiedDBIdentifier;
import org.apache.openjpa.jdbc.sql.SQLExceptions;
import org.apache.openjpa.lib.conf.Configurable;
import org.apache.openjpa.lib.conf.Configuration;
import org.apache.openjpa.lib.identifier.IdentifierRule;
/**
* Factory that uses database metadata to construct the system schema.
@ -35,6 +39,7 @@ import org.apache.openjpa.lib.conf.Configuration;
*
* @author Abe White
*/
@SuppressWarnings("serial")
public class LazySchemaFactory
extends SchemaGroup
implements SchemaFactory, Configurable {
@ -80,19 +85,49 @@ public class LazySchemaFactory
// nothing to do
}
/**
* @deprecated
*/
public Table findTable(String name) {
if (name == null)
return null;
return findTable(DBIdentifier.newTable(name));
}
Table table = super.findTable(name);
public Table findTable(DBIdentifier name) {
if (name == null)
return null;
return findTable(QualifiedDBIdentifier.getPath(name));
}
public Table findTable(QualifiedDBIdentifier path) {
if (path == null)
return null;
Table table = super.findTable(path);
if (table != null)
return table;
generateSchemaObject(name, true);
return super.findTable(name);
generateSchemaObject(path, true);
return super.findTable(path);
}
/**
* @deprecated
*/
public Sequence findSequence(String name) {
if (name == null)
return null;
return findSequence(DBIdentifier.newSequence(name));
}
public Sequence findSequence(DBIdentifier name) {
if (name == null)
return null;
return findSequence(QualifiedDBIdentifier.getPath(name));
}
public Sequence findSequence(QualifiedDBIdentifier name) {
if (name == null)
return null;
@ -107,24 +142,10 @@ public class LazySchemaFactory
/**
* Generate the table or sequence with the given name.
*/
private void generateSchemaObject(String name, boolean isTable) {
private void generateSchemaObject(QualifiedDBIdentifier name, boolean isTable) {
// if full name, split
String schemaName = null;
String objectName = name;
// look for the standard schema separator...
int dotIdx = name.indexOf('.');
// ... or the dictionary schema separator
if (dotIdx == -1) {
String sep = _conf.getDBDictionaryInstance().catalogSeparator;
if (!".".equals(sep))
dotIdx = name.indexOf(sep);
}
if (dotIdx != -1) {
schemaName = name.substring(0, dotIdx);
objectName = name.substring(dotIdx + 1);
}
DBIdentifier schemaName = name.getSchemaName();
DBIdentifier objectName = name.getIdentifier();
// we share a single connection across all schemas, so synch
// on the schema group
@ -149,18 +170,18 @@ public class LazySchemaFactory
if (table != null) {
if (_pks)
_gen.generatePrimaryKeys(table.getSchemaName(),
table.getName(), _conn, _meta);
_gen.generatePrimaryKeys(table.getSchemaIdentifier(),
table.getIdentifier(), _conn, _meta);
if (_indexes)
_gen.generateIndexes(table.getSchemaName(),
table.getName(), _conn, _meta);
_gen.generateIndexes(table.getSchemaIdentifier(),
table.getIdentifier(), _conn, _meta);
// generate foreign keys from the table; this might
// end up re-calling this getTable method if the foreign
// key links to a table that hasn't been loaded yet
if (_fks)
_gen.generateForeignKeys(table.getSchemaName(),
table.getName(), _conn, _meta);
_gen.generateForeignKeys(table.getSchemaIdentifier(),
table.getIdentifier(), _conn, _meta);
}
} else
_gen.generateSequences(schemaName, objectName, _conn,

View File

@ -21,7 +21,7 @@ package org.apache.openjpa.jdbc.schema;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.ObjectUtils;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.util.InvalidStateException;
@ -32,13 +32,14 @@ import org.apache.openjpa.util.InvalidStateException;
*
* @author Abe White
*/
@SuppressWarnings("serial")
public abstract class LocalConstraint
extends Constraint {
private static final Localizer _loc = Localizer.forPackage
(LocalConstraint.class);
private List _colList = null;
private List<Column> _colList = null;
private Column[] _cols = null;
/**
@ -52,12 +53,16 @@ public abstract class LocalConstraint
*
* @param name the name of the constraint, if any
* @param table the table of the constraint
* @deprecated
*/
public LocalConstraint(String name, Table table) {
super(name, table);
}
/**
public LocalConstraint(DBIdentifier name, Table table) {
super(name, table);
}
/**
* Called when the constraint is removed from its table.
*/
void remove() {
@ -99,7 +104,7 @@ public abstract class LocalConstraint
col == null ? null : getTable()));
if (_colList == null)
_colList = new ArrayList(3);
_colList = new ArrayList<Column>(3);
else if (_colList.contains(col))
return;
@ -168,7 +173,7 @@ public abstract class LocalConstraint
*/
private static boolean hasColumn(Column[] cols, Column col) {
for (int i = 0; i < cols.length; i++)
if (cols[i].getFullName().equalsIgnoreCase(col.getFullName()))
if (cols[i].getQualifiedPath().equals(col.getQualifiedPath()))
return true;
return false;
}

View File

@ -23,6 +23,8 @@ import java.util.HashSet;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.identifier.DBIdentifier.DBIdentifierType;
import org.apache.openjpa.lib.util.Localizer;
/**
@ -32,30 +34,47 @@ import org.apache.openjpa.lib.util.Localizer;
*
* @author Abe White
*/
@SuppressWarnings("serial")
public class NameSet
implements Serializable {
private static final Localizer _loc = Localizer.forPackage(NameSet.class);
private Set _names = null;
private Set<DBIdentifier> _names = null;
/**
* Return true if the given name is in use already.
* @deprecated
*/
public boolean isNameTaken(String name) {
if (name == null)
return isNameTaken(DBIdentifier.toUpper(DBIdentifier.newDefault(name)));
}
public boolean isNameTaken(DBIdentifier name) {
if (DBIdentifier.isEmpty(name)) {
return true;
return _names != null && _names.contains(name.toUpperCase());
}
if (_names == null) {
return false;
}
DBIdentifier sName = DBIdentifier.toUpper(name);
return _names.contains(sName);
}
/**
* @deprecated
*/
protected void addName(String name, boolean validate) {
addName(DBIdentifier.newIdentifier(name, DBIdentifierType.DEFAULT, true), validate);
}
/**
* Attempt to add the given name to the set.
*
* @param name the name to add
* @param validate if true, null or empty names will not be accepted
*/
protected void addName(String name, boolean validate) {
if (StringUtils.isEmpty(name)) {
protected void addName(DBIdentifier name, boolean validate) {
if (DBIdentifier.isNull(name) || StringUtils.isEmpty(name.getName())) {
if (validate)
throw new IllegalArgumentException(_loc.get("bad-name", name)
.getMessage());
@ -66,15 +85,27 @@ public class NameSet
// DBs use different namespaces for components, and it would be
// difficult to find a scheme that fits all and is still useful
if (_names == null)
_names = new HashSet();
_names.add(name.toUpperCase());
_names = new HashSet<DBIdentifier>();
DBIdentifier sName = DBIdentifier.toUpper(name);
_names.add(sName);
}
/**
* Remove the given name from the table.
* @deprecated
*/
protected void removeName(String name) {
if (name != null && _names != null)
_names.remove(name.toUpperCase());
if (name != null && _names != null) {
removeName(DBIdentifier.newIdentifier(name, DBIdentifierType.DEFAULT, true));
}
}
/**
* Remove the given name from the table.
*/
protected void removeName(DBIdentifier name) {
if (!DBIdentifier.isNull(name) && _names != null) {
DBIdentifier sName = DBIdentifier.toUpper(name);
_names.remove(sName);
}
}
}

View File

@ -18,6 +18,8 @@
*/
package org.apache.openjpa.jdbc.schema;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
/**
* Represents a table primary key. It can also represent a partial key,
* aligning with the key information available from
@ -25,6 +27,7 @@ package org.apache.openjpa.jdbc.schema;
*
* @author Abe White
*/
@SuppressWarnings("serial")
public class PrimaryKey
extends LocalConstraint {
@ -41,11 +44,16 @@ public class PrimaryKey
*
* @param name the name of the primary key, if any
* @param table the table of the primary key
* @deprecated
*/
public PrimaryKey(String name, Table table) {
super(name, table);
}
public PrimaryKey(DBIdentifier name, Table table) {
super(name, table);
}
public boolean isLogical() {
return _logical;
}

View File

@ -22,22 +22,22 @@ import java.io.Serializable;
import java.util.Map;
import java.util.TreeMap;
import org.apache.commons.lang.StringUtils;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.identifier.DBIdentifier.DBIdentifierType;
/**
* Represents a database schema.
*
* @author Abe White
*/
@SuppressWarnings("serial")
public class Schema
implements Comparable, Serializable {
implements Comparable<Schema>, Serializable {
private String _name = null;
private DBIdentifier _name = DBIdentifier.NULL;
private SchemaGroup _group = null;
private Map _tableMap = null;
private Map _seqMap = null;
// TODO: temp until a more global solution is implemented
private Map<String, Sequence> _delimSeqMap = null;
private Map<DBIdentifier, Table> _tableMap = null;
private Map<DBIdentifier, Sequence> _seqMap = null;
// cache
private Table[] _tables = null;
@ -54,9 +54,14 @@ public class Schema
*
* @param name the schema name, if any
* @param group the schema's owning group
* @deprecated
*/
public Schema(String name, SchemaGroup group) {
setName(name);
this(DBIdentifier.newSchema(name), group);
}
public Schema(DBIdentifier name, SchemaGroup group) {
setIdentifier(name);
_group = group;
}
@ -83,21 +88,31 @@ public class Schema
/**
* Return the name of the schema, or null if none.
* @deprecated
*/
public String getName() {
return getIdentifier().getName();
}
public DBIdentifier getIdentifier() {
return _name;
}
/**
* Set the name of the schema. This method can only be used for schemas
* not attached to a group.
* @deprecated
*/
public void setName(String name) {
if (getSchemaGroup() != null)
throw new IllegalStateException();
_name = StringUtils.trimToNull(name);
setIdentifier(DBIdentifier.trimToNull(DBIdentifier.newSchema(name)));
}
public void setIdentifier(DBIdentifier name) {
if (getSchemaGroup() != null)
throw new IllegalStateException();
_name = DBIdentifier.trimToNull(name);
}
/**
* Return the schema's tables.
*/
@ -110,35 +125,56 @@ public class Schema
/**
* Return the table with the given name, or null if none.
* @deprecated
*/
public Table getTable(String name) {
if (name == null || _tableMap == null)
return null;
return (Table) _tableMap.get(name.toUpperCase());
return getTable(DBIdentifier.newIdentifier(name, DBIdentifierType.TABLE, true));
}
public Table getTable(DBIdentifier name) {
if (DBIdentifier.isNull(name) || _tableMap == null)
return null;
DBIdentifier sName = DBIdentifier.toUpper(name);
return (Table) _tableMap.get(sName);
}
/**
* Add a table to the schema.
* @deprecated
*/
public Table addTable(String name) {
return addTable(DBIdentifier.newTable(name));
}
public Table addTable(DBIdentifier name) {
SchemaGroup group = getSchemaGroup();
Table tab;
name = name.getUnqualifiedName();
if (group != null) {
group.addName(name, true);
tab = group.newTable(name, this);
} else
tab = new Table(name, this);
if (_tableMap == null)
_tableMap = new TreeMap();
_tableMap.put(name.toUpperCase(), tab);
_tableMap = new TreeMap<DBIdentifier, Table>();
DBIdentifier sName = DBIdentifier.toUpper(name);
_tableMap.put(sName, tab);
_tables = null;
return tab;
}
/**
* Add a table with a shortened (i.e., validated) name to the schema
* @deprecated
*/
public Table addTable(String name, String validName) {
return addTable(DBIdentifier.newTable(name), DBIdentifier.newTable(validName));
}
public Table addTable(DBIdentifier name, DBIdentifier validName) {
SchemaGroup group = getSchemaGroup();
Table tab;
if (group != null) {
@ -147,8 +183,9 @@ public class Schema
} else
tab = new Table(validName, this);
if (_tableMap == null)
_tableMap = new TreeMap();
_tableMap.put(name.toUpperCase(), tab);
_tableMap = new TreeMap<DBIdentifier, Table>();
DBIdentifier sName = DBIdentifier.toUpper(name);
_tableMap.put(sName, tab);
_tables = null;
return tab;
}
@ -162,15 +199,16 @@ public class Schema
if (tab == null || _tableMap == null)
return false;
Table cur = (Table) _tableMap.get(tab.getName().toUpperCase());
DBIdentifier sName = DBIdentifier.toUpper(tab.getIdentifier());
Table cur = (Table) _tableMap.get(sName);
if (!cur.equals(tab))
return false;
_tableMap.remove(tab.getName().toUpperCase());
_tableMap.remove(sName);
_tables = null;
SchemaGroup group = getSchemaGroup();
if (group != null)
group.removeName(tab.getName());
group.removeName(tab.getIdentifier());
tab.remove();
return true;
}
@ -183,7 +221,7 @@ public class Schema
if (table == null)
return null;
Table copy = addTable(table.getName());
Table copy = addTable(table.getIdentifier());
Column[] cols = table.getColumns();
for (int i = 0; i < cols.length; i++)
copy.importColumn(cols[i]);
@ -204,22 +242,32 @@ public class Schema
/**
* Return the sequence with the given name, or null if none.
* @deprecated
*/
public Sequence getSequence(String name) {
if (name == null || _seqMap == null)
return null;
// TODO: temp until a more global solution is implemented
Sequence seq = (Sequence) _seqMap.get(name.toUpperCase());
if (seq == null && _delimSeqMap != null) {
seq = _delimSeqMap.get(name.toUpperCase());
}
return getSequence(DBIdentifier.newIdentifier(name, DBIdentifierType.SEQUENCE, true));
}
public Sequence getSequence(DBIdentifier name) {
if (DBIdentifier.isNull(name) || _seqMap == null)
return null;
DBIdentifier sName = DBIdentifier.toUpper(name);
Sequence seq = (Sequence) _seqMap.get(sName);
return seq;
}
/**
* Add a sequence to the schema.
* @deprecated
*/
public Sequence addSequence(String name) {
return addSequence(DBIdentifier.newIdentifier(name, DBIdentifierType.SEQUENCE, true));
}
public Sequence addSequence(DBIdentifier name) {
SchemaGroup group = getSchemaGroup();
Sequence seq;
if (group != null) {
@ -228,22 +276,13 @@ public class Schema
} else
seq = new Sequence(name, this);
if (_seqMap == null)
_seqMap = new TreeMap();
_seqMap.put(name.toUpperCase(), seq);
_seqMap = new TreeMap<DBIdentifier, Sequence>();
DBIdentifier sName = DBIdentifier.toUpper(name);
_seqMap.put(sName, seq);
_seqs = null;
return seq;
}
public void addDelimSequenceName(String name, Sequence seq) {
SchemaGroup group = getSchemaGroup();
if (group != null) {
group.addName(name, true);
}
if (_delimSeqMap == null) {
_delimSeqMap = new TreeMap<String, Sequence>();
}
_delimSeqMap.put(name.toUpperCase(), seq);
}
/**
* Remove the given sequence from the schema.
@ -254,15 +293,16 @@ public class Schema
if (seq == null || _seqMap == null)
return false;
Sequence cur = (Sequence) _seqMap.get(seq.getName().toUpperCase());
DBIdentifier sName = DBIdentifier.toUpper(seq.getIdentifier());
Sequence cur = (Sequence) _seqMap.get(sName);
if (!cur.equals(seq))
return false;
_seqMap.remove(seq.getName().toUpperCase());
_seqMap.remove(sName);
_seqs = null;
SchemaGroup group = getSchemaGroup();
if (group != null)
group.removeName(seq.getName());
group.removeName(seq.getIdentifier());
seq.remove();
return true;
}
@ -274,26 +314,27 @@ public class Schema
if (seq == null)
return null;
Sequence copy = addSequence(seq.getName());
Sequence copy = addSequence(seq.getIdentifier());
copy.setInitialValue(seq.getInitialValue());
copy.setIncrement(seq.getIncrement());
copy.setAllocate(seq.getAllocate());
return copy;
}
public int compareTo(Object other) {
String name = getName();
String otherName = ((Schema) other).getName();
if (name == null && otherName == null)
public int compareTo(Schema other) {
DBIdentifier name = getIdentifier();
DBIdentifier otherName = ((Schema) other).getIdentifier();
if (DBIdentifier.isNull(name) && DBIdentifier.isNull(otherName)) {
return 0;
if (name == null)
}
if (DBIdentifier.isNull(name))
return 1;
if (otherName == null)
if (DBIdentifier.isNull(otherName))
return -1;
return name.compareTo(otherName);
}
public String toString() {
return getName();
return getIdentifier().getName();
}
}

View File

@ -34,8 +34,11 @@ import java.util.Map;
import java.util.Set;
import javax.sql.DataSource;
import org.apache.commons.lang.StringUtils;
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
import org.apache.openjpa.jdbc.identifier.Normalizer;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.identifier.QualifiedDBIdentifier;
import org.apache.openjpa.jdbc.identifier.DBIdentifier.DBIdentifierType;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.lib.log.Log;
import org.apache.openjpa.lib.util.Localizer;
@ -65,7 +68,7 @@ public class SchemaGenerator {
private boolean _openjpaTables = true;
private SchemaGroup _group = null;
private List _listeners = null;
private List<Listener> _listeners = null;
private int _schemaObjects = 0;
/**
@ -85,7 +88,20 @@ public class SchemaGenerator {
_dict = conf.getDBDictionaryInstance();
// create a table of allowed schema and tables to reflect on
_allowed = parseSchemasList(conf.getSchemasList());
String[] schemaArray = conf.getSchemasList();
DBIdentifier[] names = new DBIdentifier[schemaArray == null ? 0 : schemaArray.length];
for (int i = 0; i < names.length; i++) {
String[] splitName = Normalizer.splitName(schemaArray[i]);
if (splitName == null || splitName.length == 0) {
continue;
}
if (splitName.length == 1) {
names[i] = DBIdentifier.newSchema(schemaArray[i]);
} else {
names[i] = QualifiedDBIdentifier.newTable(schemaArray[i]);
}
}
_allowed = parseSchemasList(names);
}
/**
@ -95,34 +111,25 @@ public class SchemaGenerator {
* null if no args are given. If no tables are given for a particular
* schema, maps the schema name to null.
*/
private static Object[][] parseSchemasList(String[] args) {
private static Object[][] parseSchemasList(DBIdentifier[] args) {
if (args == null || args.length == 0)
return null;
Map schemas = new HashMap();
String schema, table;
int dotIdx;
Collection tables;
Map<DBIdentifier, Collection<DBIdentifier>> schemas = new HashMap<DBIdentifier, Collection<DBIdentifier>>();
DBIdentifier schema = DBIdentifier.NULL, table = DBIdentifier.NULL;
Collection<DBIdentifier> tables = null;
for (int i = 0; i < args.length; i++) {
dotIdx = args[i].indexOf('.');
if (dotIdx == -1) {
schema = args[i];
table = null;
} else if (dotIdx == 0) {
schema = null;
table = args[i].substring(1);
} else {
schema = args[i].substring(0, dotIdx);
table = args[i].substring(dotIdx + 1);
}
QualifiedDBIdentifier path = QualifiedDBIdentifier.getPath(args[i]);
schema = path.getSchemaName();
table = path.getIdentifier();
// if just a schema name, map schema to null
if (table == null && !schemas.containsKey(schema))
if (DBIdentifier.isNull(table) && !schemas.containsKey(schema))
schemas.put(schema, null);
else if (table != null) {
tables = (Collection) schemas.get(schema);
else if (!DBIdentifier.isNull(table)) {
tables = schemas.get(schema);
if (tables == null) {
tables = new LinkedList();
tables = new LinkedList<DBIdentifier>();
schemas.put(schema, tables);
}
tables.add(table);
@ -130,15 +137,16 @@ public class SchemaGenerator {
}
Object[][] parsed = new Object[schemas.size()][2];
Map.Entry entry;
Map.Entry<DBIdentifier, Collection<DBIdentifier>> entry;
int idx = 0;
for (Iterator itr = schemas.entrySet().iterator(); itr.hasNext();) {
entry = (Map.Entry) itr.next();
tables = (Collection) entry.getValue();
for (Iterator<Map.Entry<DBIdentifier, Collection<DBIdentifier>>> itr = schemas.entrySet().iterator();
itr.hasNext();) {
entry = itr.next();
tables = entry.getValue();
parsed[idx][0] = entry.getKey();
if (tables != null)
parsed[idx][1] = tables.toArray(new String[tables.size()]);
parsed[idx][1] = tables.toArray(new DBIdentifier[tables.size()]);
idx++;
}
return parsed;
@ -240,16 +248,24 @@ public class SchemaGenerator {
public void generateSchemas()
throws SQLException {
fireGenerationEvent(_loc.get("generating-schemas"));
generateSchemas(null);
generateSchemas((DBIdentifier[])null);
}
/**
* @deprecated
*/
public void generateSchemas(String[] schemasAndTables)
throws SQLException {
generateSchemas(DBIdentifier.toArray(schemasAndTables, DBIdentifierType.TABLE));
}
/**
* Generate the schemas and/or tables named in the given strings.
* This method calls {@link #generateIndexes},
* {@link #generatePrimaryKeys}, and {@link #generateForeignKeys}
* automatically.
*/
public void generateSchemas(String[] schemasAndTables)
public void generateSchemas(DBIdentifier[] schemasAndTables)
throws SQLException {
fireGenerationEvent(_loc.get("generating-schemas"));
@ -260,10 +276,10 @@ public class SchemaGenerator {
schemaMap = parseSchemasList(schemasAndTables);
if (schemaMap == null) {
generateSchema(null, null);
generateSchema(DBIdentifier.NULL, (DBIdentifier[])null);
// estimate the number of schema objects we will need to visit
// in order to estimate progresss total for any listeners
// in order to estimate progress total for any listeners
int numTables = getTables(null).size();
_schemaObjects += numTables
+ (_pks ? numTables : 0)
@ -271,28 +287,28 @@ public class SchemaGenerator {
+ (_fks ? numTables : 0);
if (_pks)
generatePrimaryKeys(null, null);
generatePrimaryKeys(DBIdentifier.NULL, null);
if (_indexes)
generateIndexes(null, null);
generateIndexes(DBIdentifier.NULL, null);
if (_fks)
generateForeignKeys(null, null);
generateForeignKeys(DBIdentifier.NULL, null);
return;
}
// generate all schemas and tables
for (int i = 0; i < schemaMap.length; i++)
generateSchema((String) schemaMap[i][0],
(String[]) schemaMap[i][1]);
generateSchema((DBIdentifier) schemaMap[i][0],
(DBIdentifier[]) schemaMap[i][1]);
// generate pks, indexes, fks
String schemaName;
String[] tableNames;
DBIdentifier schemaName = DBIdentifier.NULL;
DBIdentifier[] tableNames;
for (int i = 0; i < schemaMap.length; i++) {
schemaName = (String) schemaMap[i][0];
tableNames = (String[]) schemaMap[i][1];
schemaName = (DBIdentifier) schemaMap[i][0];
tableNames = (DBIdentifier[]) schemaMap[i][1];
// estimate the number of schema objects we will need to visit
// in order to estimate progresss total for any listeners
// in order to estimate progress total for any listeners
int numTables = (tableNames != null) ? tableNames.length
: getTables(schemaName).size();
_schemaObjects += numTables
@ -309,6 +325,17 @@ public class SchemaGenerator {
}
}
/**
* @param name
* @param tableNames
* @deprecated
*/
public void generateSchema(String name, String[] tableNames)
throws SQLException {
generateSchema(DBIdentifier.newSchema(name),
DBIdentifier.toArray(tableNames, DBIdentifierType.TABLE));
}
/**
* Add a fully-constructed {@link Schema} matching the given database
* schema to the current group. No foreign keys are generated because
@ -320,7 +347,7 @@ public class SchemaGenerator {
* @param tableNames a list of tables to generate in the schema, or null
* to generate all tables
*/
public void generateSchema(String name, String[] tableNames)
public void generateSchema(DBIdentifier name, DBIdentifier[] tableNames)
throws SQLException {
fireGenerationEvent(_loc.get("generating-schema", name));
@ -329,13 +356,13 @@ public class SchemaGenerator {
DatabaseMetaData meta = conn.getMetaData();
try {
if (tableNames == null)
generateTables(name, null, conn, meta);
generateTables(name, DBIdentifier.NULL, conn, meta);
else
for (int i = 0; i < tableNames.length; i++)
generateTables(name, tableNames[i], conn, meta);
if (_seqs)
generateSequences(name, null, conn, meta);
generateSequences(name, DBIdentifier.NULL, conn, meta);
} finally {
// some databases require a commit after metadata to release locks
try {
@ -355,8 +382,23 @@ public class SchemaGenerator {
* only be called after all schemas are generated. The schema name and
* tables array can be null to indicate that indexes should be generated
* for all schemas and/or tables.
* @deprecated
*/
public void generatePrimaryKeys(String schemaName, String[] tableNames)
throws SQLException {
generatePrimaryKeys(DBIdentifier.newSchema(schemaName),
DBIdentifier.toArray(tableNames, DBIdentifierType.TABLE));
}
/**
* Generate primary key information for the given schema. This method
* must be called in addition to {@link #generateSchema}. It should
* only be called after all schemas are generated. The schema name and
* tables array can be null to indicate that indexes should be generated
* for all schemas and/or tables.
*/
public void generatePrimaryKeys(DBIdentifier schemaName, DBIdentifier[] tableNames)
throws SQLException {
fireGenerationEvent(_loc.get("generating-all-primaries", schemaName));
@ -387,8 +429,22 @@ public class SchemaGenerator {
* only be called after all schemas are generated. The schema name and
* tables array can be null to indicate that indexes should be generated
* for all schemas and/or tables.
* @deprecated
*/
public void generateIndexes(String schemaName, String[] tableNames)
public void generateIndexes(String schemaName, String[] tableNames)
throws SQLException {
generateIndexes(DBIdentifier.newSchema(schemaName),
DBIdentifier.toArray(tableNames, DBIdentifierType.TABLE));
}
/**
* Generate index information for the given schema. This method
* must be called in addition to {@link #generateSchema}. It should
* only be called after all schemas are generated. The schema name and
* tables array can be null to indicate that indexes should be generated
* for all schemas and/or tables.
*/
public void generateIndexes(DBIdentifier schemaName, DBIdentifier[] tableNames)
throws SQLException {
fireGenerationEvent(_loc.get("generating-all-indexes", schemaName));
@ -419,8 +475,23 @@ public class SchemaGenerator {
* only be called after all schemas are generated. The schema name and
* tables array can be null to indicate that indexes should be generated
* for all schemas and/or tables.
* @deprecated
*/
public void generateForeignKeys(String schemaName, String[] tableNames)
throws SQLException {
generateForeignKeys(DBIdentifier.newSchema(schemaName),
DBIdentifier.toArray(tableNames, DBIdentifierType.TABLE));
}
/**
* Generate foreign key information for the given schema. This method
* must be called in addition to {@link #generateSchema}. It should
* only be called after all schemas are generated. The schema name and
* tables array can be null to indicate that indexes should be generated
* for all schemas and/or tables.
*/
public void generateForeignKeys(DBIdentifier schemaName, DBIdentifier[] tableNames)
throws SQLException {
fireGenerationEvent(_loc.get("generating-all-foreigns", schemaName));
@ -446,9 +517,19 @@ public class SchemaGenerator {
}
/**
* Adds all tables matching the given name pattern to the schema.
* @deprecated
*/
public void generateTables(String schemaName, String tableName,
Connection conn, DatabaseMetaData meta)
throws SQLException {
generateTables(DBIdentifier.newSchema(schemaName),
DBIdentifier.newTable(tableName), conn, meta);
}
/**
* Adds all tables matching the given name pattern to the schema.
*/
public void generateTables(DBIdentifier schemaName, DBIdentifier tableName,
Connection conn, DatabaseMetaData meta)
throws SQLException {
fireGenerationEvent(_loc.get("generating-columns", schemaName,
@ -456,43 +537,47 @@ public class SchemaGenerator {
if (_log.isTraceEnabled())
_log.trace(_loc.get("gen-tables", schemaName, tableName));
Column[] cols = _dict.getColumns(meta, conn.getCatalog(), schemaName,
Column[] cols = _dict.getColumns(meta,
DBIdentifier.newCatalog(conn.getCatalog()), schemaName,
tableName, null, conn);
// when we want to get all the columns for all tables, we need to build
// a list of tables to verify because some databases (e.g., Postgres)
// will include indexes in the list of columns, and there is no way to
// distinguish the indexes from proper columns
Set tableNames = null;
if (tableName == null || "%".equals(tableName)) {
Table[] tables = _dict.getTables(meta, conn.getCatalog(),
Set<DBIdentifier> tableNames = null;
if (DBIdentifier.isNull(tableName) || "%".equals(tableName.getName())) {
Table[] tables = _dict.getTables(meta, DBIdentifier.newCatalog(conn.getCatalog()),
schemaName, tableName, conn);
tableNames = new HashSet();
tableNames = new HashSet<DBIdentifier>();
for (int i = 0; tables != null && i < tables.length; i++) {
if (cols == null)
tableNames.add(tables[i].getName());
else
tableNames.add(tables[i].getName().toUpperCase());
if (cols == null) {
tableNames.add(tables[i].getIdentifier());
}
else {
DBIdentifier sName = DBIdentifier.toUpper(tables[i].getIdentifier());
tableNames.add(sName);
}
}
}
// if database can't handle null table name, recurse on each known name
if (cols == null && tableName == null) {
for (Iterator itr = tableNames.iterator(); itr.hasNext();)
generateTables(schemaName, (String) itr.next(), conn, meta);
if (cols == null && DBIdentifier.isNull(tableName)) {
for (Iterator<DBIdentifier> itr = tableNames.iterator(); itr.hasNext();)
generateTables(schemaName, itr.next(), conn, meta);
return;
}
SchemaGroup group = getSchemaGroup();
Schema schema;
Table table;
String tableSchema;
DBIdentifier tableSchema = DBIdentifier.NULL;
for (int i = 0; cols != null && i < cols.length; i++) {
if (tableName == null || tableName.equals("%")) {
tableName = cols[i].getTableName();
if (DBIdentifier.isNull(tableName) || tableName.equals("%")) {
tableName = cols[i].getTableIdentifier();
}
if (schemaName == null) {
tableSchema = StringUtils.trimToNull(cols[i].getSchemaName());
if (DBIdentifier.isNull(schemaName)) {
tableSchema = DBIdentifier.trimToNull(cols[i].getSchemaIdentifier());
}
else {
tableSchema = schemaName;
@ -500,15 +585,16 @@ public class SchemaGenerator {
// ignore special tables
if (!_openjpaTables &&
(tableName.toUpperCase().startsWith("OPENJPA_")
|| tableName.toUpperCase().startsWith("JDO_"))) // legacy
(tableName.getName().toUpperCase().startsWith("OPENJPA_")
|| tableName.getName().toUpperCase().startsWith("JDO_"))) // legacy
continue;
if (_dict.isSystemTable(tableName, tableSchema, schemaName != null))
if (_dict.isSystemTable(tableName, tableSchema, !DBIdentifier.isNull(schemaName)))
continue;
// ignore tables not in list, or not allowed by schemas property
if (tableNames != null
&& !tableNames.contains(tableName.toUpperCase()))
&& !tableNames.contains(DBIdentifier.toUpper(tableName)))
continue;
if (!isAllowedTable(tableSchema, tableName))
continue;
@ -525,9 +611,9 @@ public class SchemaGenerator {
}
if (_log.isTraceEnabled())
_log.trace(_loc.get("gen-column", cols[i].getName(), table));
_log.trace(_loc.get("gen-column", cols[i].getIdentifier(), table));
if (table.getColumn(cols[i].getName(), _dict) == null) {
if (table.getColumn(cols[i].getIdentifier()) == null) {
table.importColumn(cols[i]);
}
}
@ -536,30 +622,30 @@ public class SchemaGenerator {
/**
* Return whether the given table is allowed by the user's schema list.
*/
private boolean isAllowedTable(String schema, String table) {
private boolean isAllowedTable(DBIdentifier schema, DBIdentifier table) {
if (_allowed == null)
return true;
// do case-insensitive comparison on allowed table and schema names
String[] tables;
String[] anySchemaTables = null;
DBIdentifier[] tables;
DBIdentifier[] anySchemaTables = null;
for (int i = 0; i < _allowed.length; i++) {
if (_allowed[i][0] == null) {
anySchemaTables = (String[]) _allowed[i][1];
anySchemaTables = (DBIdentifier[]) _allowed[i][1];
if (schema == null)
break;
continue;
}
if (!StringUtils.equalsIgnoreCase(schema, (String) _allowed[i][0]))
if (!schema.equals((DBIdentifier) _allowed[i][0]))
continue;
if (table == null)
return true;
tables = (String[]) _allowed[i][1];
tables = (DBIdentifier[]) _allowed[i][1];
if (tables == null)
return true;
for (int j = 0; j < tables.length; j++)
if (StringUtils.equalsIgnoreCase(table, tables[j]))
if (table.equals(tables[j]))
return true;
}
@ -567,7 +653,7 @@ public class SchemaGenerator {
if (table == null)
return true;
for (int i = 0; i < anySchemaTables.length; i++)
if (StringUtils.equalsIgnoreCase(table, anySchemaTables[i]))
if (table.equals(anySchemaTables[i]))
return true;
}
return false;
@ -575,8 +661,16 @@ public class SchemaGenerator {
/**
* Generates table primary keys.
* @deprecated
*/
public void generatePrimaryKeys(String schemaName, String tableName,
Connection conn, DatabaseMetaData meta)
throws SQLException {
generatePrimaryKeys(DBIdentifier.newSchema(schemaName), DBIdentifier.newTable(tableName),
conn, meta);
}
public void generatePrimaryKeys(DBIdentifier schemaName, DBIdentifier tableName,
Connection conn, DatabaseMetaData meta)
throws SQLException {
fireGenerationEvent(_loc.get("generating-primary",
@ -586,53 +680,63 @@ public class SchemaGenerator {
// if looking for a non-existant table, just return
SchemaGroup group = getSchemaGroup();
if (tableName != null && group.findTable(tableName) == null)
if (tableName != null && !tableName.isNull() &&
group.findTable(QualifiedDBIdentifier.getPath(tableName)) == null)
return;
// if the database can't use a table name wildcard, recurse on each
// concrete table in the requested schema(s)
PrimaryKey[] pks = _dict.getPrimaryKeys(meta, conn.getCatalog(),
PrimaryKey[] pks = _dict.getPrimaryKeys(meta,
DBIdentifier.newCatalog(conn.getCatalog()),
schemaName, tableName, conn);
Table table;
if (pks == null && tableName == null) {
Collection tables = getTables(schemaName);
for (Iterator itr = tables.iterator(); itr.hasNext();) {
Collection<Table> tables = getTables(schemaName);
for (Iterator<Table> itr = tables.iterator(); itr.hasNext();) {
table = (Table) itr.next();
generatePrimaryKeys(table.getSchemaName(),
table.getName(), conn, meta);
generatePrimaryKeys(table.getSchemaIdentifier(),
table.getIdentifier(), conn, meta);
}
return;
}
Schema schema;
PrimaryKey pk;
String name;
String colName;
DBIdentifier name = DBIdentifier.NULL;
DBIdentifier colName = DBIdentifier.NULL;
for (int i = 0; pks != null && i < pks.length; i++) {
schemaName = StringUtils.trimToNull(pks[i].getSchemaName());
schemaName = DBIdentifier.trimToNull(schemaName);
schema = group.getSchema(schemaName);
if (schema == null)
continue;
table = schema.getTable(pks[i].getTableName());
table = schema.getTable(pks[i].getTableIdentifier());
if (table == null)
continue;
colName = pks[i].getColumnName();
name = pks[i].getName();
colName = pks[i].getColumnIdentifier();
name = pks[i].getIdentifier();
if (_log.isTraceEnabled())
_log.trace(_loc.get("gen-pk", name, table, colName));
pk = table.getPrimaryKey();
if (pk == null)
pk = table.addPrimaryKey(name);
pk.addColumn(table.getColumn(colName, _dict));
pk.addColumn(table.getColumn(colName));
}
}
/**
* Generates table indexes.
* @deprecated
*/
public void generateIndexes(String schemaName, String tableName,
Connection conn, DatabaseMetaData meta)
throws SQLException {
generateIndexes(DBIdentifier.newSchema(schemaName), DBIdentifier.newTable(tableName),
conn, meta);
}
public void generateIndexes(DBIdentifier schemaName, DBIdentifier tableName,
Connection conn, DatabaseMetaData meta)
throws SQLException {
fireGenerationEvent(_loc.get("generating-indexes",
@ -642,52 +746,52 @@ public class SchemaGenerator {
// if looking for a non-existant table, just return
SchemaGroup group = getSchemaGroup();
if (tableName != null && group.findTable(tableName) == null)
if (tableName != null && group.findTable(QualifiedDBIdentifier.getPath(tableName)) == null)
return;
// if the database can't use a table name wildcard, recurse on each
// concrete table in the requested schema(s)
Index[] idxs = _dict.getIndexInfo(meta, conn.getCatalog(),
Index[] idxs = _dict.getIndexInfo(meta, DBIdentifier.newCatalog(conn.getCatalog()),
schemaName, tableName, false, true, conn);
Table table;
if (idxs == null && tableName == null) {
Collection tables = getTables(schemaName);
for (Iterator itr = tables.iterator(); itr.hasNext();) {
table = (Table) itr.next();
generateIndexes(table.getSchemaName(),
table.getName(), conn, meta);
Collection<Table> tables = getTables(schemaName);
for (Iterator<Table> itr = tables.iterator(); itr.hasNext();) {
table = itr.next();
generateIndexes(table.getSchemaIdentifier(),
table.getIdentifier(), conn, meta);
}
return;
}
Schema schema;
Index idx;
String name;
String colName;
String pkName;
DBIdentifier name = DBIdentifier.NULL;
DBIdentifier colName = DBIdentifier.NULL;
DBIdentifier pkName = DBIdentifier.NULL;
for (int i = 0; idxs != null && i < idxs.length; i++) {
schemaName = StringUtils.trimToNull(idxs[i].getSchemaName());
schemaName = DBIdentifier.trimToNull(idxs[i].getSchemaIdentifier());
schema = group.getSchema(schemaName);
if (schema == null)
continue;
table = schema.getTable(idxs[i].getTableName());
table = schema.getTable(idxs[i].getTableIdentifier());
if (table == null)
continue;
if (table.getPrimaryKey() != null)
pkName = table.getPrimaryKey().getName();
pkName = table.getPrimaryKey().getIdentifier();
else
pkName = null;
// statistics don't have names; skip them
name = idxs[i].getName();
if (StringUtils.isEmpty(name)
|| (pkName != null && name.equalsIgnoreCase(pkName))
name = idxs[i].getIdentifier();
if (DBIdentifier.isEmpty(name)
|| (pkName != null && name.equals(pkName))
|| _dict.isSystemIndex(name, table))
continue;
colName = idxs[i].getColumnName();
if (table.getColumn(colName, _dict) == null)
colName = idxs[i].getColumnIdentifier();
if (table.getColumn(colName) == null)
continue;
if (_log.isTraceEnabled())
@ -699,7 +803,7 @@ public class SchemaGenerator {
idx = table.addIndex(name);
idx.setUnique(idxs[i].isUnique());
}
idx.addColumn(table.getColumn(colName, _dict));
idx.addColumn(table.getColumn(colName));
}
}
@ -707,6 +811,13 @@ public class SchemaGenerator {
* Generates table foreign keys.
*/
public void generateForeignKeys(String schemaName, String tableName,
Connection conn, DatabaseMetaData meta)
throws SQLException {
generateForeignKeys(DBIdentifier.newSchema(schemaName), DBIdentifier.newTable(tableName),
conn, meta);
}
public void generateForeignKeys(DBIdentifier schemaName, DBIdentifier tableName,
Connection conn, DatabaseMetaData meta)
throws SQLException {
fireGenerationEvent(_loc.get("generating-foreign",
@ -716,20 +827,20 @@ public class SchemaGenerator {
// if looking for a non-existant table, just return
SchemaGroup group = getSchemaGroup();
if (tableName != null && group.findTable(tableName) == null)
if (!DBIdentifier.isNull(tableName) && group.findTable(QualifiedDBIdentifier.getPath(tableName)) == null)
return;
// if the database can't use a table name wildcard, recurse on each
// concrete table in the requested schema(s)
ForeignKey[] fks = _dict.getImportedKeys(meta, conn.getCatalog(),
ForeignKey[] fks = _dict.getImportedKeys(meta, DBIdentifier.newCatalog(conn.getCatalog()),
schemaName, tableName, conn);
Table table;
if (fks == null && tableName == null) {
Collection tables = getTables(schemaName);
for (Iterator itr = tables.iterator(); itr.hasNext();) {
table = (Table) itr.next();
generateForeignKeys(table.getSchemaName(),
table.getName(), conn, meta);
if (fks == null && DBIdentifier.isNull(tableName)) {
Collection<Table> tables = getTables(schemaName);
for (Iterator<Table> itr = tables.iterator(); itr.hasNext();) {
table = itr.next();
generateForeignKeys(table.getSchemaIdentifier(),
table.getIdentifier(), conn, meta);
}
return;
}
@ -737,26 +848,26 @@ public class SchemaGenerator {
Schema schema;
Table pkTable;
ForeignKey fk;
String name;
String pkSchemaName;
String pkTableName;
String pkColName;
String fkColName;
DBIdentifier name = DBIdentifier.NULL;
DBIdentifier pkSchemaName = DBIdentifier.NULL;
DBIdentifier pkTableName = DBIdentifier.NULL;
DBIdentifier pkColName = DBIdentifier.NULL;
DBIdentifier fkColName = DBIdentifier.NULL;
int seq;
boolean seqWas0 = false; // some drivers incorrectly start at 0
Collection invalids = null;
Collection<ForeignKey> invalids = null;
for (int i = 0; fks != null && i < fks.length; i++) {
schemaName = StringUtils.trimToNull(fks[i].getSchemaName());
schemaName = DBIdentifier.trimToNull(fks[i].getSchemaIdentifier());
schema = group.getSchema(schemaName);
if (schema == null)
continue;
table = schema.getTable(fks[i].getTableName());
table = schema.getTable(fks[i].getTableIdentifier());
if (table == null)
continue;
name = fks[i].getName();
fkColName = fks[i].getColumnName();
pkColName = fks[i].getPrimaryKeyColumnName();
name = fks[i].getIdentifier();
fkColName = fks[i].getColumnIdentifier();
pkColName = fks[i].getPrimaryKeyColumnIdentifier();
seq = fks[i].getKeySequence();
if (seq == 0)
seqWas0 = true;
@ -764,18 +875,16 @@ public class SchemaGenerator {
seq++;
// find pk table
pkSchemaName = fks[i].getPrimaryKeySchemaName();
pkSchemaName = fks[i].getPrimaryKeySchemaIdentifier();
if(_dict.getTrimSchemaName()) {
pkSchemaName= StringUtils.trimToNull(pkSchemaName);
pkSchemaName= DBIdentifier.trimToNull(pkSchemaName);
}
pkTableName = fks[i].getPrimaryKeyTableName();
pkTableName = fks[i].getPrimaryKeyTableIdentifier();
if (_log.isTraceEnabled())
_log.trace(_loc.get("gen-fk", new Object[]{ name, table,
fkColName, pkTableName, pkColName, seq + "" }));
if (!StringUtils.isEmpty(pkSchemaName))
pkTableName = pkSchemaName + "." + pkTableName;
pkTable = group.findTable(pkTableName);
pkTable = group.findTable(QualifiedDBIdentifier.newPath(pkSchemaName, pkTableName));
if (pkTable == null)
throw new SQLException(_loc.get("gen-nofktable",
table, pkTableName).getMessage());
@ -799,18 +908,18 @@ public class SchemaGenerator {
if (invalids == null || !invalids.contains(fk)) {
try {
Column fkCol = table.getColumn(fkColName, _dict);
Column fkCol = table.getColumn(fkColName);
if (fkCol == null) {
throw new IllegalArgumentException(_loc.get(
"no-column", fkColName, table.getName())
"no-column", fkColName, table.getIdentifier())
.getMessage());
}
fk.join(fkCol, pkTable.getColumn(pkColName, _dict));
fk.join(fkCol, pkTable.getColumn(pkColName));
} catch (IllegalArgumentException iae) {
if (_log.isWarnEnabled())
_log.warn(_loc.get("bad-join", iae.toString()));
if (invalids == null)
invalids = new HashSet();
invalids = new HashSet<ForeignKey>();
invalids.add(fk);
}
}
@ -818,8 +927,8 @@ public class SchemaGenerator {
// remove invalid fks
if (invalids != null) {
for (Iterator itr = invalids.iterator(); itr.hasNext();) {
fk = (ForeignKey) itr.next();
for (Iterator<ForeignKey> itr = invalids.iterator(); itr.hasNext();) {
fk = itr.next();
fk.getTable().removeForeignKey(fk);
}
}
@ -827,8 +936,16 @@ public class SchemaGenerator {
/**
* Adds all sequences matching the given name pattern to the schema.
* @deprecated
*/
public void generateSequences(String schemaName, String sequenceName,
Connection conn, DatabaseMetaData meta)
throws SQLException {
generateSequences(DBIdentifier.newSchema(schemaName),
DBIdentifier.newSequence(sequenceName), conn, meta);
}
public void generateSequences(DBIdentifier schemaName, DBIdentifier sequenceName,
Connection conn, DatabaseMetaData meta)
throws SQLException {
fireGenerationEvent(_loc.get("generating-sequences", schemaName));
@ -837,20 +954,21 @@ public class SchemaGenerator {
// since all the sequences are generated under the default schema
// therefore, we can use the null schemaname to search
Sequence[] seqs = _dict.getSequences(meta, conn.getCatalog(),
null, sequenceName, conn);
Sequence[] seqs = _dict.getSequences(meta, DBIdentifier.newCatalog(conn.getCatalog()),
DBIdentifier.NULL, sequenceName, conn);
SchemaGroup group = getSchemaGroup();
Schema schema;
String sequenceSchema;
DBIdentifier sequenceSchema = DBIdentifier.NULL;
for (int i = 0; seqs != null && i < seqs.length; i++) {
sequenceName = seqs[i].getName();
sequenceSchema = StringUtils.trimToNull(seqs[i].getSchemaName());
sequenceName = seqs[i].getIdentifier();
sequenceSchema = DBIdentifier.trimToNull(seqs[i].getSchemaIdentifier());
// ignore special tables
String seqUpper = DBIdentifier.toUpper(sequenceName).getName();
if (!_openjpaTables &&
(sequenceName.toUpperCase().startsWith("OPENJPA_")
|| sequenceName.toUpperCase().startsWith("JDO_"))) // legacy
(seqUpper.startsWith("OPENJPA_")
|| seqUpper.startsWith("JDO_"))) // legacy
continue;
if (_dict.isSystemSequence(sequenceName, sequenceSchema,
schemaName != null))
@ -859,27 +977,12 @@ public class SchemaGenerator {
continue;
schema = group.getSchema(sequenceSchema);
if (schema == null) {
// TODO: temp until a more global name solution is implemented
schema = group.getSchema(_dict.addDelimiters(sequenceSchema));
// schema = group.getSchema(_dict.delimitString(sequenceSchema,
// DBDictionary.DBIdentifiers.SEQUENCE_GEN_SCHEMA));
}
if (schema == null) {
schema = group.addSchema(sequenceSchema);
// TODO: temp until a more global solution is implemented
// group.addDelimSchemaName(_dict.delimitString(sequenceSchema,
// DBDictionary.DBIdentifiers.SEQUENCE_GEN_SCHEMA), schema);
group.addDelimSchemaName(_dict.addDelimiters(sequenceSchema), schema);
}
if (schema.getSequence(sequenceName) == null) {
Sequence seq = schema.addSequence(sequenceName);
// TODO: temp until a more global solution is implemented
// schema.addDelimSequenceName(_dict.delimitString(sequenceName,
// DBDictionary.DBIdentifiers.SEQUENCE_GEN_SEQ_NAME), seq);
schema.addDelimSequenceName(_dict.addDelimiters(sequenceName), seq);
schema.addSequence(sequenceName);
}
}
}
@ -895,8 +998,8 @@ public class SchemaGenerator {
return;
Event e = new Event(schemaObject, _schemaObjects);
for (Iterator i = _listeners.iterator(); i.hasNext();) {
Listener l = (Listener) i.next();
for (Iterator<Listener> i = _listeners.iterator(); i.hasNext();) {
Listener l = i.next();
if (!l.schemaObjectGenerated(e))
throw new SQLException(_loc.get("refresh-cancelled")
.getMessage());
@ -910,7 +1013,7 @@ public class SchemaGenerator {
*/
public void addListener(Listener l) {
if (_listeners == null)
_listeners = new LinkedList();
_listeners = new LinkedList<Listener>();
_listeners.add(l);
}
@ -928,17 +1031,17 @@ public class SchemaGenerator {
* Return all tables for the given schema name, or all tables in
* the schema group if null is given.
*/
private Collection getTables(String schemaName) {
private Collection<Table> getTables(DBIdentifier schemaName) {
SchemaGroup group = getSchemaGroup();
if (schemaName != null) {
if (!DBIdentifier.isNull(schemaName)) {
Schema schema = group.getSchema(schemaName);
if (schema == null)
return Collections.EMPTY_LIST;
return Collections.emptyList();
return Arrays.asList(schema.getTables());
}
Schema[] schemas = group.getSchemas();
Collection tables = new LinkedList();
Collection<Table> tables = new LinkedList<Table>();
for (int i = 0; i < schemas.length; i++)
tables.addAll(Arrays.asList(schemas[i].getTables()));
return tables;
@ -955,6 +1058,7 @@ public class SchemaGenerator {
/**
* An event corresponding to the generation of a schema object.
*/
@SuppressWarnings("serial")
public class Event
extends EventObject {

View File

@ -23,17 +23,20 @@ import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.identifier.QualifiedDBIdentifier;
/**
* Represents a grouping of schemas used in a database.
*
* @author Abe White
*/
@SuppressWarnings("serial")
public class SchemaGroup
extends NameSet
implements Cloneable {
private Map _schemaMap = null;
private Map<String, Schema> _delimSchemaMap = null;
private Map<DBIdentifier, Schema> _schemaMap = null;
// cache
private Schema[] _schemas = null;
@ -50,54 +53,52 @@ public class SchemaGroup
/**
* Return the schema with the given name, or null if none.
* @deprecated
*/
public Schema getSchema(String name) {
if (_schemaMap == null)
return null;
if (name != null)
name = name.toUpperCase();
// TODO: temp until a more global solution is implemented
Schema schema = (Schema) _schemaMap.get(name);
if (schema == null && _delimSchemaMap != null) {
schema = _delimSchemaMap.get(name);
}
return getSchema(DBIdentifier.toUpper(DBIdentifier.newSchema(name)));
}
public Schema getSchema(DBIdentifier name) {
if (_schemaMap == null)
return null;
DBIdentifier sName = DBIdentifier.toUpper(name);
Schema schema = (Schema) _schemaMap.get(sName);
return schema;
// return (Schema) _schemaMap.get(name);
}
/**
* Add a schema to the group.
*/
public Schema addSchema() {
return addSchema(null);
return addSchema(DBIdentifier.NULL);
}
/**
* Add a schema to the group.
*/
public Schema addSchema(String name) {
public Schema addSchema(DBIdentifier name) {
addName(name, false);
Schema schema = newSchema(name);
if (name != null)
name = name.toUpperCase();
DBIdentifier sName = DBIdentifier.toUpper(name);
if (_schemaMap == null)
_schemaMap = new HashMap();
_schemaMap.put(name, schema);
_schemaMap = new HashMap<DBIdentifier, Schema>();
_schemaMap.put(sName, schema);
_schemas = null;
return schema;
}
// TODO: temp until a more global solution is implemented
public void addDelimSchemaName(String name, Schema schema) {
addName(name,false);
if (name != null)
name = name.toUpperCase();
if (_delimSchemaMap == null) {
_delimSchemaMap = new HashMap<String, Schema>();
}
_delimSchemaMap.put(name, schema);
}
/**
* @deprecated
* @param name
* @return
*/
public Schema addSchema(String name) {
return addSchema(DBIdentifier.newSchema(name));
}
/**
* Remove the given schema from the group.
*
@ -107,13 +108,11 @@ public class SchemaGroup
if (schema == null)
return false;
String name = schema.getName();
if (name != null)
name = name.toUpperCase();
DBIdentifier name = DBIdentifier.toUpper(schema.getIdentifier());
Schema rem = (Schema) _schemaMap.get(name);
if (schema.equals(rem)) {
_schemaMap.remove(name);
removeName(schema.getName());
removeName(schema.getIdentifier());
_schemas = null;
schema.remove();
return true;
@ -128,7 +127,7 @@ public class SchemaGroup
if (schema == null)
return null;
Schema copy = addSchema(schema.getName());
Schema copy = addSchema(schema.getIdentifier());
Sequence[] seqs = schema.getSequences();
for (int i = 0; i < seqs.length; i++)
copy.importSequence(seqs[i]);
@ -164,39 +163,50 @@ public class SchemaGroup
* {@link #findTable} may exhibit dynamic behavior in some schema group
* implementations, this method only returns true if the table has been
* added to this group or is known to exist in the database.
* @deprecated
*/
public boolean isKnownTable(String name) {
return findTable(name) != null;
}
public boolean isKnownTable(QualifiedDBIdentifier path) {
return findTable(path) != null;
}
/**
* Find the equivalent of the given table in this schema group. The
* given table that may have come from another schema group.
*/
public Table findTable(Table table) {
return findTable(table.getFullName());
return findTable(table.getQualifiedPath());
}
/**
* Find the table with the given name in the group, using '.' as the
* catalog separator. Returns null if no table found.
* @deprecated
*/
public Table findTable(String name) {
if (name == null)
return null;
int dotIdx = name.indexOf('.');
if (dotIdx != -1) {
String schemaName = name.substring(0, dotIdx);
name = name.substring(dotIdx + 1);
Schema schema = getSchema(schemaName);
return findTable(QualifiedDBIdentifier.getPath(DBIdentifier.newTable(name)));
}
public Table findTable(QualifiedDBIdentifier path) {
if (DBIdentifier.isNull(path)) {
return null;
}
if (!DBIdentifier.isNull(path.getSchemaName())) {
Schema schema = getSchema(path.getSchemaName());
if (schema != null)
return schema.getTable(name);
return schema.getTable(path.getUnqualifiedName());
} else {
Schema[] schemas = getSchemas();
Table tab;
for (int i = 0; i < schemas.length; i++) {
tab = schemas[i].getTable(name);
tab = schemas[i].getTable(path.getIdentifier());
if (tab != null)
return tab;
}
@ -207,30 +217,38 @@ public class SchemaGroup
/**
* Find the table with the given name in the group, using '.' as the catalog
* separator. Returns null if no table found.
* @deprecated
*/
public Table findTable(Schema inSchema, String name) {
return findTable(inSchema, name, null);
}
/**
* Find the table with the given name in the group, using '.' as the catalog
* separator. Returns null if no table found.
*/
public Table findTable(Schema inSchema, String name, String defaultSchemaName) {
if (name == null)
return null;
return findTable(inSchema, DBIdentifier.newTable(name), DBIdentifier.NULL);
}
int dotIdx = name.indexOf('.');
if (dotIdx != -1) {
String schemaName = name.substring(0, dotIdx);
name = name.substring(dotIdx + 1);
Schema schema = getSchema(schemaName);
public Table findTable(Schema inSchema, DBIdentifier name) {
if (DBIdentifier.isNull(name))
return null;
return findTable(inSchema, QualifiedDBIdentifier.getPath(name), DBIdentifier.NULL);
}
public Table findTable(Schema inSchema, DBIdentifier name, DBIdentifier defaultSchemaName) {
if (DBIdentifier.isNull(name))
return null;
return findTable(inSchema, QualifiedDBIdentifier.getPath(name), defaultSchemaName);
}
public Table findTable(Schema inSchema, QualifiedDBIdentifier path, DBIdentifier defaultSchemaName) {
if (path == null)
return null;
if (!DBIdentifier.isNull(path.getSchemaName())) {
Schema schema = getSchema(path.getSchemaName());
if (schema != null)
return schema.getTable(name);
return schema.getTable(path.getIdentifier());
} else {
Schema[] schemas = getSchemas();
for (int i = 0; i < schemas.length; i++) {
Table tab = schemas[i].getTable(name);
Table tab = schemas[i].getTable(path.getIdentifier());
// if a table is found and it has the same schema
// as the input schema , it means that the table
// exists. However, if the input schema is null,
@ -239,11 +257,11 @@ public class SchemaGroup
// We can't handle the case that one entity has schema name
// and other entity does not have schema name but both entities
// map to the same table.
boolean isDefaultSchema = inSchema.getName() == null &&
defaultSchemaName != null &&
defaultSchemaName.equalsIgnoreCase(schemas[i].getName());
boolean hasNoDefaultSchema = inSchema.getName() == null &&
defaultSchemaName == null;
boolean isDefaultSchema = DBIdentifier.isNull(inSchema.getIdentifier()) &&
!DBIdentifier.isNull(defaultSchemaName) &&
DBIdentifier.equalsIgnoreCase(defaultSchemaName, schemas[i].getIdentifier());
boolean hasNoDefaultSchema = DBIdentifier.isNull(inSchema.getIdentifier()) &&
DBIdentifier.isNull(defaultSchemaName);
if (tab != null &&
(schemas[i] == inSchema || isDefaultSchema || hasNoDefaultSchema))
@ -269,39 +287,58 @@ public class SchemaGroup
* {@link #findSequence} may exhibit dynamic behavior in some schema group
* implementations, this method only returns true if the sequence has been
* added to this group or is known to exist in the database.
* @deprecated
*/
public boolean isKnownSequence(String name) {
return findSequence(name) != null;
}
public boolean isKnownSequence(DBIdentifier name) {
return findSequence(QualifiedDBIdentifier.getPath(name)) != null;
}
public boolean isKnownSequence(QualifiedDBIdentifier path) {
return findSequence(path) != null;
}
/**
* Find the equivalent of the given sequence in this schema group. The
* given sequence that may have come from another schema group.
*/
public Sequence findSequence(Sequence seq) {
return findSequence(seq.getFullName());
return findSequence(QualifiedDBIdentifier.getPath(seq.getIdentifier()));
}
/**
* Find the sequence with the given name in the group, using '.' as the
* catalog separator. Returns null if no sequence found.
* @deprecated
*/
public Sequence findSequence(String name) {
if (name == null)
return null;
return findSequence(DBIdentifier.newSequence(name));
}
int dotIdx = name.indexOf('.');
if (dotIdx != -1) {
String schemaName = name.substring(0, dotIdx);
name = name.substring(dotIdx + 1);
Schema schema = getSchema(schemaName);
public Sequence findSequence(DBIdentifier name) {
if (DBIdentifier.isNull(name))
return null;
return findSequence(QualifiedDBIdentifier.getPath(name));
}
public Sequence findSequence(QualifiedDBIdentifier path) {
if (path == null)
return null;
if (!DBIdentifier.isNull(path.getSchemaName())) {
Schema schema = getSchema(path.getSchemaName());
if (schema != null)
return schema.getSequence(name);
return schema.getSequence(path.getIdentifier());
} else {
Schema[] schemas = getSchemas();
Sequence seq;
for (int i = 0; i < schemas.length; i++) {
seq = schemas[i].getSequence(name);
seq = schemas[i].getSequence(path.getIdentifier());
if (seq != null)
return seq;
}
@ -312,28 +349,32 @@ public class SchemaGroup
/**
* Find the sequence with the given name in the group, using '.' as the
* catalog separator. Returns null if no sequence found.
* @deprecated
*/
public Sequence findSequence(Schema inSchema, String name) {
if (name == null)
return null;
return findSequence(inSchema, QualifiedDBIdentifier.getPath(DBIdentifier.newSequence(name)));
}
int dotIdx = name.indexOf('.');
if (dotIdx != -1) {
String schemaName = name.substring(0, dotIdx);
name = name.substring(dotIdx + 1);
Schema schema = getSchema(schemaName);
public Sequence findSequence(Schema inSchema, QualifiedDBIdentifier path) {
if (path == null)
return null;
if (!DBIdentifier.isNull(path.getSchemaName())) {
Schema schema = getSchema(path.getSchemaName());
if (schema != null)
return schema.getSequence(name);
return schema.getSequence(path.getIdentifier());
} else {
Schema[] schemas = getSchemas();
Sequence seq;
for (int i = 0; i < schemas.length; i++) {
seq = schemas[i].getSequence(name);
seq = schemas[i].getSequence(path.getIdentifier());
if ((seq != null) &&
(schemas[i] == inSchema || inSchema.getName() == null))
(schemas[i] == inSchema || DBIdentifier.isNull(inSchema.getIdentifier())))
return seq;
}
}
return null;
}
@ -349,7 +390,7 @@ public class SchemaGroup
Schema[] schemas = getSchemas();
Table[] tabs;
ForeignKey[] fks;
Collection exports = new LinkedList();
Collection<ForeignKey> exports = new LinkedList<ForeignKey>();
for (int i = 0; i < schemas.length; i++) {
tabs = schemas[i].getTables();
for (int j = 0; j < tabs.length; j++) {
@ -436,65 +477,106 @@ public class SchemaGroup
for (int j = 0; j < tabs.length; j++) {
fks = tabs[j].getForeignKeys();
for (int k = 0; k < fks.length; k++)
getSchema(schemas[i].getName()).getTable
(tabs[j].getName()).importForeignKey(fks[k]);
getSchema(schemas[i].getIdentifier()).getTable
(tabs[j].getIdentifier()).importForeignKey(fks[k]);
}
}
}
/**
* Return a new schema with the given name.
* @deprecated
*/
protected Schema newSchema(String name) {
return new Schema(name, this);
}
protected Schema newSchema(DBIdentifier name) {
return new Schema(name, this);
}
/**
* Return a new sequence with the given name and owner schema.
* @deprecated
*/
protected Sequence newSequence(String name, Schema schema) {
return new Sequence(name, schema);
}
protected Sequence newSequence(DBIdentifier name, Schema schema) {
return new Sequence(name, schema);
}
/**
* Return a new table with the given name and owner schema.
* @deprecated
*/
protected Table newTable(String name, Schema schema) {
return new Table(name, schema);
}
protected Table newTable(DBIdentifier name, Schema schema) {
return new Table(name, schema);
}
/**
* Return a new column with the given name and owner table.
* @deprecated
*/
protected Column newColumn(String name, Table table) {
return new Column(name, table);
}
protected Column newColumn(DBIdentifier name, Table table) {
return new Column(name, table);
}
/**
* Return a new primary key with the given name and owner table.
* @deprecated
*/
protected PrimaryKey newPrimaryKey(String name, Table table) {
return new PrimaryKey(name, table);
}
protected PrimaryKey newPrimaryKey(DBIdentifier name, Table table) {
return new PrimaryKey(name, table);
}
/**
* Return a new index with the given name and owner table.
* @deprecated
*/
protected Index newIndex(String name, Table table) {
return new Index(name, table);
}
protected Index newIndex(DBIdentifier name, Table table) {
return new Index(name, table);
}
/**
* Return a new unique constraint with the given name and owner table.
* @deprecated
*/
protected Unique newUnique(String name, Table table) {
return new Unique(name, table);
}
protected Unique newUnique(DBIdentifier name, Table table) {
return new Unique(name, table);
}
/**
* Return a new foreign key with the given name and owner table.
* @deprecated
*/
protected ForeignKey newForeignKey(String name, Table table) {
return new ForeignKey(name, table);
}
protected ForeignKey newForeignKey(DBIdentifier name, Table table) {
return new ForeignKey(name, table);
}
}

View File

@ -39,10 +39,13 @@ import org.apache.commons.lang.StringUtils;
import org.apache.openjpa.conf.OpenJPAConfiguration;
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
import org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.jdbc.sql.SQLExceptions;
import org.apache.openjpa.lib.conf.Configurations;
import org.apache.openjpa.lib.identifier.IdentifierUtil;
import org.apache.openjpa.lib.log.Log;
import org.apache.openjpa.lib.meta.MetaDataSerializer;
import org.apache.openjpa.lib.util.Files;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.lib.util.Options;
@ -416,7 +419,7 @@ public class SchemaTool {
throws SQLException {
SchemaGroup group = getSchemaGroup();
Schema[] schemas = group.getSchemas();
Collection tables = new LinkedHashSet();
Collection<Table> tables = new LinkedHashSet<Table>();
for (int i = 0; i < schemas.length; i++) {
Table[] ts = schemas[i].getTables();
for (int j = 0; j < ts.length; j++)
@ -451,14 +454,14 @@ public class SchemaTool {
for (int i = 0; i < schemas.length; i++) {
seqs = schemas[i].getSequences();
for (int j = 0; j < seqs.length; j++) {
if (db.findSequence(schemas[i], seqs[j].getFullName()) !=
if (db.findSequence(schemas[i], seqs[j].getQualifiedPath()) !=
null)
continue;
if (createSequence(seqs[j])) {
schema = db.getSchema(seqs[j].getSchemaName());
schema = db.getSchema(seqs[j].getSchemaIdentifier());
if (schema == null)
schema = db.addSchema(seqs[j].getSchemaName());
schema = db.addSchema(seqs[j].getSchemaIdentifier());
schema.importSequence(seqs[j]);
} else
_log.warn(_loc.get("add-seq", seqs[j]));
@ -471,31 +474,23 @@ public class SchemaTool {
Table dbTable;
Column[] cols;
Column col;
String delim = _dict.getDelimiter();
String defaultSchemaName = _dict.getDefaultSchemaName();
DBIdentifier defaultSchemaName = DBIdentifier.newSchema(_dict.getDefaultSchemaName());
for (int i = 0; i < schemas.length; i++) {
tabs = schemas[i].getTables();
for (int j = 0; j < tabs.length; j++) {
cols = tabs[j].getColumns();
dbTable = db.findTable(schemas[i], tabs[j].getFullName(), defaultSchemaName);
dbTable = db.findTable(schemas[i], tabs[j].getQualifiedPath(), defaultSchemaName);
for (int k = 0; k < cols.length; k++) {
if (dbTable != null) {
String colName = cols[k].getName();
boolean delimCol = false;
if (colName.startsWith(delim)
&& colName.endsWith(delim)) {
colName = colName.substring(1, colName.length()-1);
delimCol = true;
}
col = dbTable.getColumn(colName, _dict);
DBIdentifier colName = cols[k].getIdentifier();
col = dbTable.getColumn(colName);
if (col == null) {
if (addColumn(cols[k]))
dbTable.importColumn(cols[k]);
else
_log.warn(_loc.get("add-col", cols[k],
tabs[j]));
// TODO: Find a way to compare these with delimCol
} else if (!delimCol && !cols[k].equalsColumn(col)) {
} else if (!cols[k].equalsColumn(col)) {
_log.warn(_loc.get("bad-col", new Object[]{
col, dbTable, col.getDescription(),
cols[k].getDescription() }));
@ -512,7 +507,7 @@ public class SchemaTool {
tabs = schemas[i].getTables();
for (int j = 0; j < tabs.length; j++) {
pk = tabs[j].getPrimaryKey();
dbTable = db.findTable(schemas[i], tabs[j].getFullName());
dbTable = db.findTable(schemas[i], tabs[j].getQualifiedPath());
if (pk != null && !pk.isLogical() && dbTable != null) {
if (dbTable.getPrimaryKey() == null
&& addPrimaryKey(pk))
@ -528,18 +523,18 @@ public class SchemaTool {
}
// tables
Set newTables = new HashSet();
Set<Table> newTables = new HashSet<Table>();
for (int i = 0; i < schemas.length; i++) {
tabs = schemas[i].getTables();
for (int j = 0; j < tabs.length; j++) {
if (db.findTable(schemas[i], tabs[j].getFullName()) != null)
if (db.findTable(schemas[i], tabs[j].getQualifiedPath()) != null)
continue;
if (createTable(tabs[j])) {
newTables.add(tabs[j]);
schema = db.getSchema(tabs[j].getSchemaName());
schema = db.getSchema(tabs[j].getSchemaIdentifier());
if (schema == null)
schema = db.addSchema(tabs[j].getSchemaName());
schema = db.addSchema(tabs[j].getSchemaIdentifier());
schema.importTable(tabs[j]);
} else
_log.warn(_loc.get("add-table", tabs[j]));
@ -558,7 +553,7 @@ public class SchemaTool {
continue;
idxs = tabs[j].getIndexes();
dbTable = db.findTable(schemas[i], tabs[j].getFullName());
dbTable = db.findTable(schemas[i], tabs[j].getQualifiedPath());
for (int k = 0; k < idxs.length; k++) {
if (dbTable != null) {
idx = findIndex(dbTable, idxs[k]);
@ -608,7 +603,7 @@ public class SchemaTool {
continue;
fks = tabs[j].getForeignKeys();
dbTable = db.findTable(schemas[i],tabs[j].getFullName());
dbTable = db.findTable(schemas[i],tabs[j].getQualifiedPath());
for (int k = 0; k < fks.length; k++) {
if (!fks[k].isLogical() && dbTable != null) {
fk = findForeignKey(dbTable, fks[k]);
@ -715,7 +710,7 @@ public class SchemaTool {
// columns
Column[] cols;
Column col;
Collection drops = new LinkedList();
Collection<Table> drops = new LinkedList<Table>();
for (int i = 0; i < schemas.length; i++) {
tabs = schemas[i].getTables();
for (int j = 0; j < tabs.length; j++) {
@ -725,7 +720,7 @@ public class SchemaTool {
reposTable = repos.findTable(tabs[j]);
if (reposTable != null) {
for (int k = 0; k < cols.length; k++) {
col = reposTable.getColumn(cols[k].getName(), _dict);
col = reposTable.getColumn(cols[k].getIdentifier());
if (col == null || !cols[k].equalsColumn(col)) {
if (tabs[j].getColumns().length == 1)
drops.add(tabs[j]);
@ -782,7 +777,7 @@ public class SchemaTool {
// calculate tables to drop; we can only drop tables if we're sure
// the user listed the entire table definition in the stuff they want
// dropped; else they might just want to drop a few columns
Collection drops = new LinkedList();
Collection<Table> drops = new LinkedList<Table>();
Table[] tabs;
Table dbTable;
Column[] dbCols;
@ -798,7 +793,7 @@ public class SchemaTool {
dbCols = dbTable.getColumns();
for (int k = 0; k < dbCols.length; k++)
if (tabs[j].getColumn(dbCols[k].getName(), _dict) == null)
if (tabs[j].getColumn(dbCols[k].getIdentifier()) == null)
continue tables;
drops.add(tabs[j]);
@ -838,8 +833,8 @@ public class SchemaTool {
// also drop imported foreign keys for tables that will be dropped
Table tab;
for (Iterator itr = drops.iterator(); itr.hasNext();) {
tab = (Table) itr.next();
for (Iterator<Table> itr = drops.iterator(); itr.hasNext();) {
tab = itr.next();
dbTable = db.findTable(tab);
if (dbTable == null)
continue;
@ -870,7 +865,7 @@ public class SchemaTool {
for (int k = 0; k < cols.length; k++) {
col = null;
if (dbTable != null)
col = dbTable.getColumn(cols[k].getName(), _dict);
col = dbTable.getColumn(cols[k].getIdentifier());
if (dbTable == null || col == null)
continue;
@ -890,8 +885,8 @@ public class SchemaTool {
*/
private boolean isDroppable(Table table) {
return _openjpaTables
|| (!table.getName().toUpperCase().startsWith("OPENJPA_")
&& !table.getName().toUpperCase().startsWith("JDO_")); // legacy
|| (!DBIdentifier.toUpper(table.getIdentifier()).getName().startsWith("OPENJPA_")
&& !DBIdentifier.toUpper(table.getIdentifier()).getName().startsWith("JDO_")); // legacy
}
/**
@ -899,8 +894,8 @@ public class SchemaTool {
*/
private boolean isDroppable(Sequence seq) {
return _openjpaTables
|| (!seq.getName().toUpperCase().startsWith("OPENJPA_")
&& !seq.getName().toUpperCase().startsWith("JDO_")); // legacy
|| (!DBIdentifier.toUpper(seq.getIdentifier()).getName().startsWith("OPENJPA_")
&& !DBIdentifier.toUpper(seq.getIdentifier()).getName().startsWith("JDO_")); // legacy
}
/**
@ -933,15 +928,15 @@ public class SchemaTool {
* Remove the given collection of tables from the database schema. Orders
* the removals according to foreign key constraints on the tables.
*/
private void dropTables(Collection tables, SchemaGroup change)
private void dropTables(Collection<Table> tables, SchemaGroup change)
throws SQLException {
if (tables.isEmpty())
return;
Table table;
Table changeTable;
for (Iterator itr = tables.iterator(); itr.hasNext();) {
table = (Table) itr.next();
for (Iterator<Table> itr = tables.iterator(); itr.hasNext();) {
table = itr.next();
if (dropTable(table)) {
changeTable = change.findTable(table);
if (changeTable != null)
@ -1128,22 +1123,24 @@ public class SchemaTool {
// group; some may not exist yet, which is OK; we just need
// to make sure we can detect the changes to the ones that
// do exist
Collection tables = new LinkedList();
Collection<DBIdentifier> tables = new LinkedList<DBIdentifier>();
SchemaGroup group = assertSchemaGroup();
Schema[] schemas = group.getSchemas();
Table[] tabs;
for (int i = 0; i < schemas.length; i++) {
tabs = schemas[i].getTables();
for (int j = 0; j < tabs.length; j++) {
if (tabs[j].getSchemaName() == null)
tables.add("." + tabs[j].getName());
else
tables.add(tabs[j].getFullName());
if (DBIdentifier.isNull(tabs[j].getSchemaIdentifier())) {
tables.add(tabs[j].getIdentifier());
} else {
DBIdentifier sName = tabs[j].getFullIdentifier();
tables.add(sName);
}
}
}
if (!tables.isEmpty())
gen.generateSchemas((String[]) tables.toArray
(new String[tables.size()]));
gen.generateSchemas((DBIdentifier[]) tables.toArray
(new DBIdentifier[tables.size()]));
}
_db = gen.getSchemaGroup();
}
@ -1448,7 +1445,7 @@ public class SchemaTool {
log.info(_loc.get("sch-reflect-write"));
SchemaSerializer ser = new XMLSchemaSerializer(conf);
ser.addAll(gen.getSchemaGroup());
ser.serialize(flags.writer, ser.PRETTY);
ser.serialize(flags.writer, MetaDataSerializer.PRETTY);
return true;
}
@ -1486,7 +1483,7 @@ public class SchemaTool {
log.info(_loc.get("tool-export-write"));
SchemaSerializer ser = new XMLSchemaSerializer(conf);
ser.addAll(schema);
ser.serialize(flags.writer, ser.PRETTY);
ser.serialize(flags.writer, MetaDataSerializer.PRETTY);
return true;
}

View File

@ -21,7 +21,10 @@ package org.apache.openjpa.jdbc.schema;
import java.sql.Types;
import java.util.Date;
import org.apache.commons.lang.StringUtils;
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
import org.apache.openjpa.jdbc.identifier.Normalizer;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
/**
* Helper class to deal with schemas.
@ -40,20 +43,24 @@ public class Schemas {
/**
* Return the schema name that should be used for new tables, or null if
* none.
* @deprecated
*/
public static String getNewTableSchema(JDBCConfiguration conf) {
return getNewTableSchemaIdentifier(conf).getName();
}
public static DBIdentifier getNewTableSchemaIdentifier(JDBCConfiguration conf) {
if (conf.getSchema() != null)
return conf.getSchema();
return DBIdentifier.newSchema(conf.getSchema());
String[] schemas = conf.getSchemasList();
if (schemas.length == 0)
return null;
int dotIdx = schemas[0].lastIndexOf('.');
if (dotIdx == 0)
return null;
if (dotIdx == -1)
return schemas[0];
return schemas[0].substring(0, dotIdx);
return DBIdentifier.NULL;
String[] names = Normalizer.splitName(schemas[0]);
if (names.length == 0 || StringUtils.isEmpty(names[0])) {
return DBIdentifier.NULL;
}
return DBIdentifier.newSchema(names[0]);
}
/**
@ -190,7 +197,7 @@ public class Schemas {
/**
* Return the java type for the given SQL type from {@link Types}.
*/
public static Class getJavaType(int type, int size, int decimals) {
public static Class<?> getJavaType(int type, int size, int decimals) {
switch (type) {
case Types.CHAR:
if (size == 1)

View File

@ -20,6 +20,10 @@ package org.apache.openjpa.jdbc.schema;
import java.io.File;
import org.apache.openjpa.jdbc.identifier.Normalizer;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.identifier.QualifiedDBIdentifier;
import org.apache.openjpa.lib.identifier.IdentifierUtil;
import org.apache.openjpa.lib.meta.SourceTracker;
/**
@ -27,20 +31,21 @@ import org.apache.openjpa.lib.meta.SourceTracker;
*
* @author Abe White
*/
@SuppressWarnings("serial")
public class Sequence
extends ReferenceCounter
implements Comparable, SourceTracker {
implements Comparable<Sequence>, SourceTracker {
private String _name = null;
private String _fullName = null;
private DBIdentifier _name = DBIdentifier.NULL;
private Schema _schema = null;
private String _schemaName = null;
private DBIdentifier _schemaName = DBIdentifier.NULL;
private int _initial = 1;
private int _increment = 1;
private int _cache = 0;
private int _lineNum = 0;
private int _colNum = 0;
private QualifiedDBIdentifier _fullPath = null;
// keep track of source
private File _source = null;
private int _srcType = SRC_OTHER;
@ -56,11 +61,16 @@ public class Sequence
*
* @param name the sequence name
* @param schema the sequence schema
* @deprecated
*/
public Sequence(String name, Schema schema) {
setName(name);
this(DBIdentifier.newSequence(name), schema);
}
public Sequence(DBIdentifier name, Schema schema) {
setIdentifier(name);
if (schema != null)
setSchemaName(schema.getName());
setSchemaIdentifier(schema.getIdentifier());
_schema = schema;
}
@ -69,7 +79,7 @@ public class Sequence
*/
void remove() {
_schema = null;
_fullName = null;
_fullPath = null;
}
/**
@ -83,51 +93,75 @@ public class Sequence
* The sequence's schema name.
*/
public String getSchemaName() {
return _schemaName;
return getSchemaIdentifier().getName();
}
public DBIdentifier getSchemaIdentifier() {
return _schemaName == null ? DBIdentifier.NULL : _schemaName;
}
/**
* The sequence's schema name. You can only call this method on sequences
* whose schema object is not set.
* @deprecated
*/
public void setSchemaName(String name) {
setSchemaIdentifier(DBIdentifier.newSchema(name));
}
public void setSchemaIdentifier(DBIdentifier name) {
if (getSchema() != null)
throw new IllegalStateException();
_schemaName = name;
_fullName = null;
_fullPath = null;
}
/**
* Return the name of the sequence.
* @deprecated
*/
public String getName() {
return _name;
return getIdentifier().getName();
}
public DBIdentifier getIdentifier() {
return _name == null ? DBIdentifier.NULL : _name;
}
/**
* Set the name of the sequence. This method can only be called on
* sequences that are not part of a schema.
* @deprecated
*/
public void setName(String name) {
setIdentifier(DBIdentifier.newSequence(name));
}
public void setIdentifier(DBIdentifier name) {
if (getSchema() != null)
throw new IllegalStateException();
_name = name;
_fullName = null;
_fullPath = null;
}
/**
* Return the sequence name, including schema, using '.' as the
* catalog separator.
* @deprecated
*/
public String getFullName() {
if (_fullName == null) {
Schema schema = getSchema();
if (schema == null || schema.getName() == null)
_fullName = getName();
else
_fullName = schema.getName() + "." + getName();
return getFullIdentifier().getName();
}
public DBIdentifier getFullIdentifier() {
return getQualifiedPath().getIdentifier();
}
public QualifiedDBIdentifier getQualifiedPath() {
if (_fullPath == null) {
_fullPath = QualifiedDBIdentifier.newPath(_schemaName, _name );
}
return _fullName;
return _fullPath;
}
/**
@ -190,23 +224,24 @@ public class Sequence
}
public String getResourceName() {
return getFullName();
return getFullIdentifier().getName();
}
public int compareTo(Object other) {
String name = getFullName();
String otherName = ((Sequence) other).getFullName();
if (name == null && otherName == null)
public int compareTo(Sequence other) {
DBIdentifier name = getIdentifier();
DBIdentifier otherName = other.getIdentifier();
if (DBIdentifier.isNull(name) && DBIdentifier.isNull(otherName)) {
return 0;
if (name == null)
}
if (DBIdentifier.isNull(name))
return 1;
if (otherName == null)
if (DBIdentifier.isNull(otherName))
return -1;
return name.compareTo(otherName);
}
public String toString() {
return getFullName();
return getFullIdentifier().getName();
}
public int getLineNumber() {
@ -224,4 +259,5 @@ public class Sequence
public void setColNumber(int colNum) {
_colNum = colNum;
}
}

View File

@ -26,8 +26,13 @@ import java.util.Map;
import java.util.TreeMap;
import java.util.LinkedHashMap;
import org.apache.commons.lang.StringUtils;
import org.apache.openjpa.jdbc.identifier.Normalizer;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.identifier.DBIdentifierUtilImpl;
import org.apache.openjpa.jdbc.identifier.QualifiedDBIdentifier;
import org.apache.openjpa.jdbc.identifier.DBIdentifier.DBIdentifierType;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.lib.identifier.IdentifierUtil;
import org.apache.openjpa.lib.meta.SourceTracker;
/**
@ -36,16 +41,17 @@ import org.apache.openjpa.lib.meta.SourceTracker;
* @author Abe White
* @author Stephen Kim
*/
@SuppressWarnings("serial")
public class Table
extends NameSet
implements Comparable, SourceTracker {
implements Comparable<Object>, SourceTracker {
private String _name = null;
private String _schemaName = null;
private Map _colMap = null;
private Map _idxMap = null;
private Collection _fkList = null;
private Collection _unqList = null;
private DBIdentifier _name = DBIdentifier.NULL;
private DBIdentifier _schemaName = DBIdentifier.NULL;
private Map<DBIdentifier, Column> _colMap = null;
private Map<DBIdentifier, Index> _idxMap = null;
private Collection<ForeignKey> _fkList = null;
private Collection<Unique> _unqList = null;
private Schema _schema = null;
private PrimaryKey _pk = null;
@ -54,7 +60,6 @@ public class Table
private int _srcType = SRC_OTHER;
// cache
private String _fullName = null;
private Column[] _cols = null;
private Column[] _autoAssign = null;
private Column[] _rels = null;
@ -65,6 +70,7 @@ public class Table
private int _lineNum = 0;
private int _colNum = 0;
private boolean _isAssociation = false;
private QualifiedDBIdentifier _fullPath = null;
/**
* Default constructor.
@ -77,12 +83,17 @@ public class Table
*
* @param name the table name
* @param schema the table schema
* @deprecated
*/
public Table(String name, Schema schema) {
setName(name);
this(DBIdentifier.newTable(name), schema);
}
public Table(DBIdentifier name, Schema schema) {
setIdentifier(name);
addName(name, true);
if (schema != null)
setSchemaName(schema.getName());
setSchemaIdentifier(schema.getIdentifier());
_schema = schema;
}
@ -113,8 +124,8 @@ public class Table
for (int i = 0; i < cols.length; i++)
removeColumn(cols[i]);
_schema = null;
_schemaName = null;
_fullName = null;
_schemaName = DBIdentifier.NULL;
_fullPath = null;
}
/**
@ -126,53 +137,78 @@ public class Table
/**
* The table's schema name.
* @deprecated
*/
public String getSchemaName() {
return _schemaName;
return getSchemaIdentifier().getName();
}
public DBIdentifier getSchemaIdentifier() {
return _schemaName == null ? DBIdentifier.NULL : _schemaName;
}
/**
* The table's schema name. You can only call this method on tables
* whose schema object is not set.
* @deprecated
*/
public void setSchemaName(String name) {
setSchemaIdentifier(DBIdentifier.newSchema(name));
}
public void setSchemaIdentifier(DBIdentifier name) {
if (getSchema() != null)
throw new IllegalStateException();
_schemaName = name;
_fullName = null;
_fullPath = null;
}
/**
* Return the name of the table.
* @deprecated
*/
public String getName() {
return _name;
return getIdentifier().getName();
}
public DBIdentifier getIdentifier() {
return _name == null ? DBIdentifier.NULL : _name;
}
/**
* Set the name of the table. This method can only be called on tables
* that are not part of a schema.
* @deprecated
*/
public void setName(String name) {
setIdentifier(DBIdentifier.newTable(name));
}
public void setIdentifier(DBIdentifier name) {
if (getSchema() != null)
throw new IllegalStateException();
_name = name;
_fullName = null;
_fullPath = null;
}
/**
* Return the table name, including schema, using '.' as the
* catalog separator.
* @deprecated
*/
public String getFullName() {
if (_fullName == null) {
Schema schema = getSchema();
if (schema == null || schema.getName() == null)
_fullName = getName();
else
_fullName = schema.getName() + "." + getName();
return getFullIdentifier().getName();
}
public QualifiedDBIdentifier getQualifiedPath() {
if (_fullPath == null) {
_fullPath = QualifiedDBIdentifier.newPath(_schemaName, _name );
}
return _fullName;
return _fullPath;
}
public DBIdentifier getFullIdentifier() {
return getQualifiedPath().getIdentifier();
}
public File getSourceFile() {
@ -193,7 +229,7 @@ public class Table
}
public String getResourceName() {
return getFullName();
return getFullIdentifier().getName();
}
/**
@ -205,7 +241,7 @@ public class Table
_cols = Schemas.EMPTY_COLUMNS;
else {
Column[] cols = new Column[_colMap.size()];
Iterator itr = _colMap.values().iterator();
Iterator<Column> itr = _colMap.values().iterator();
for (int i = 0; itr.hasNext(); i++) {
cols[i] = (Column) itr.next();
cols[i].setIndex(i);
@ -224,12 +260,12 @@ public class Table
if (_colMap == null)
_autoAssign = Schemas.EMPTY_COLUMNS;
else {
Collection autos = null;
Collection<Column> autos = null;
Column[] cols = getColumns();
for (int i = 0; i < cols.length; i++) {
if (cols[i].isAutoAssigned()) {
if (autos == null)
autos = new ArrayList(3);
autos = new ArrayList<Column>(3);
autos.add(cols[i]);
}
}
@ -248,12 +284,12 @@ public class Table
if (_colMap == null)
_rels = Schemas.EMPTY_COLUMNS;
else {
Collection rels = null;
Collection<Column> rels = null;
Column[] cols = getColumns();
for (int i = 0; i < cols.length; i++) {
if (cols[i].isRelationId()) {
if (rels == null)
rels = new ArrayList(3);
rels = new ArrayList<Column>(3);
rels.add(cols[i]);
}
}
@ -265,47 +301,40 @@ public class Table
}
public String[] getColumnNames() {
return _colMap == null ? new String[0] :
(String[])_colMap.keySet().toArray(new String[_colMap.size()]);
if (_colMap == null) {
return new String[0];
}
DBIdentifier[] sNames = (DBIdentifier[])_colMap.keySet().toArray(new DBIdentifier[_colMap.size()]);
return DBIdentifier.toStringArray(sNames);
}
/**
* Return the column with the given name, or null if none.
* @deprecated
*/
public Column getColumn(String name) {
return getColumn(name, null);
return getColumn(DBIdentifier.newIdentifier(name, DBIdentifierType.COLUMN, true));
}
/**
* Return the column with the given name, or null if none.
* @param dict the current database dictionary or null.
*/
public Column getColumn(String name, DBDictionary dict) {
if (name == null || _colMap == null)
public Column getColumn(DBIdentifier name) {
if (DBIdentifier.isNull(name) || _colMap == null)
return null;
Column col = (Column)_colMap.get(name.toUpperCase());
if (col == null) {
String delim = null;
if (dict != null) {
delim = dict.getDelimiter();
}
else {
delim = "\"";
}
String delimName = delim + name + delim;
col = (Column) _colMap.get(delimName.toUpperCase());
}
return col;
return _colMap.get(DBIdentifier.toUpper(name));
}
/**
* Affirms if this table contains the column of the given name without any
* side-effect.
* @see Table#getColumn(String) can have side-effect of creating a column
* for dynamic table implementation.
* @deprecated
*/
public boolean containsColumn(String name) {
return containsColumn(DBIdentifier.newColumn(name), null);
}
public boolean containsColumn(DBIdentifier name) {
return containsColumn(name, null);
}
@ -315,53 +344,58 @@ public class Table
* @param dict the current database dictionary or null.
* @see Table#getColumn(String) can have side-effect of creating a column
* for dynamic table implementation.
* @deprecated
*/
public boolean containsColumn(String name, DBDictionary dict) {
if (name == null || _colMap == null) {
return false;
}
if (_colMap.containsKey(name.toUpperCase())) {
return true;
return containsColumn(DBIdentifier.newIdentifier(name, DBIdentifierType.COLUMN, true));
}
public boolean containsColumn(DBIdentifier name, DBDictionary dict) {
if (DBIdentifier.isNull(name) || _colMap == null) {
return false;
}
String delim = null;
if (dict != null) {
delim = dict.getDelimiter();
}
else {
delim = "\"";
}
String delimName = delim + name + delim;
if (_colMap.containsKey(delimName.toUpperCase())) {
return true;
}
return false;
DBIdentifier sName = DBIdentifier.toUpper(name);
return _colMap.containsKey(sName);
}
/**
* Add a column to the table.
* @deprecated
*/
public Column addColumn(String name) {
return addColumn(DBIdentifier.newColumn(name));
}
public Column addColumn(DBIdentifier name) {
addName(name, true);
Schema schema = getSchema();
Column col;
if (schema != null && schema.getSchemaGroup() != null)
if (schema != null && schema.getSchemaGroup() != null) {
col = schema.getSchemaGroup().newColumn(name, this);
else
} else {
col = new Column(name, this);
}
if (_colMap == null)
_colMap = new LinkedHashMap();
_colMap.put(name.toUpperCase(), col);
_colMap = new LinkedHashMap<DBIdentifier, Column>();
DBIdentifier sName = DBIdentifier.toUpper(name);
_colMap.put(sName, col);
_cols = null;
return col;
}
/**
* Add a colum with a shortened (i.e., validated) name to the table
* Add a column with a shortened (i.e., validated) name to the table
* @deprecated
*/
public Column addColumn(String name, String validName) {
return addColumn(DBIdentifier.newColumn(name), DBIdentifier.newColumn(validName));
}
public Column addColumn(DBIdentifier name, DBIdentifier validName) {
addName(name, true);
Schema schema = getSchema();
Column col;
@ -370,16 +404,22 @@ public class Table
else
col = new Column(validName, this);
if (_colMap == null)
_colMap = new LinkedHashMap();
_colMap.put(name.toUpperCase(), col);
_colMap = new LinkedHashMap<DBIdentifier, Column>();
DBIdentifier sName = DBIdentifier.toUpper(name);
_colMap.put(sName, col);
_cols = null;
return col;
}
/**
* Add a name to this NameSet
* @deprecated
*/
public void addCorrectedColumnName(String name, boolean validate) {
addName(DBIdentifier.newColumn(name), validate);
}
public void addCorrectedColumnName(DBIdentifier name, boolean validate) {
addName(name, validate);
}
@ -393,12 +433,13 @@ public class Table
if (col == null || _colMap == null)
return false;
Column cur = (Column) _colMap.get(col.getName().toUpperCase());
DBIdentifier sName = DBIdentifier.toUpper(col.getIdentifier());
Column cur = (Column) _colMap.get(sName);
if (!col.equals(cur))
return false;
removeName(col.getName());
_colMap.remove(col.getName().toUpperCase());
removeName(sName);
_colMap.remove(sName);
_cols = null;
if (col.isAutoAssigned())
_autoAssign = null;
@ -415,9 +456,9 @@ public class Table
if (col == null)
return null;
Column copy = addColumn(col.getName());
Column copy = addColumn(col.getIdentifier());
copy.setType(col.getType());
copy.setTypeName(col.getTypeName());
copy.setTypeIdentifier(col.getTypeIdentifier());
copy.setJavaType(col.getJavaType());
copy.setNotNull(col.isNotNull());
copy.setDefaultString(col.getDefaultString());
@ -438,13 +479,18 @@ public class Table
* Set the primary key for the table.
*/
public PrimaryKey addPrimaryKey() {
return addPrimaryKey(null);
return addPrimaryKey(DBIdentifier.NULL);
}
/**
* Set the primary key for the table.
* @deprecated
*/
public PrimaryKey addPrimaryKey(String name) {
return addPrimaryKey(DBIdentifier.newConstraint(name));
}
public PrimaryKey addPrimaryKey(DBIdentifier name) {
Schema schema = getSchema();
if (schema != null && schema.getSchemaGroup() != null) {
schema.getSchemaGroup().addName(name, false);
@ -464,7 +510,7 @@ public class Table
if (rem) {
Schema schema = getSchema();
if (schema != null && schema.getSchemaGroup() != null)
schema.getSchemaGroup().removeName(_pk.getName());
schema.getSchemaGroup().removeName(_pk.getIdentifier());
_pk.remove();
}
_pk = null;
@ -478,23 +524,30 @@ public class Table
if (pk == null)
return null;
PrimaryKey copy = addPrimaryKey(pk.getName());
PrimaryKey copy = addPrimaryKey(pk.getIdentifier());
copy.setLogical(pk.isLogical());
Column[] cols = pk.getColumns();
for (int i = 0; i < cols.length; i++)
copy.addColumn(getColumn(cols[i].getName()));
copy.addColumn(getColumn(cols[i].getIdentifier()));
return copy;
}
/**
* Return the foreign key with the given name. If multiple foreign keys
* have the name, the first match is returned.
* @deprecated
*/
public ForeignKey getForeignKey(String name) {
return getForeignKey(DBIdentifier.newForeignKey(name));
}
public ForeignKey getForeignKey(DBIdentifier name) {
ForeignKey[] fks = getForeignKeys();
for (int i = 0; i < fks.length; i++)
if (StringUtils.equalsIgnoreCase(name, fks[i].getName()))
for (int i = 0; i < fks.length; i++) {
if (name.equals(fks[i].getIdentifier())) {
return fks[i];
}
}
return null;
}
@ -507,7 +560,7 @@ public class Table
_fks = Schemas.EMPTY_FOREIGN_KEYS;
else {
ForeignKey[] fks = new ForeignKey[_fkList.size()];
Iterator itr = _fkList.iterator();
Iterator<ForeignKey> itr = _fkList.iterator();
for (int i = 0; itr.hasNext(); i++) {
fks[i] = (ForeignKey) itr.next();
fks[i].setIndex(i);
@ -522,13 +575,18 @@ public class Table
* Add a foreign key to the table.
*/
public ForeignKey addForeignKey() {
return addForeignKey(null);
return addForeignKey(DBIdentifier.NULL);
}
/**
* Add a foreign key to the table. Duplicate key names are not allowed.
* @deprecated
*/
public ForeignKey addForeignKey(String name) {
return addForeignKey(DBIdentifier.newForeignKey(name));
}
public ForeignKey addForeignKey(DBIdentifier name) {
Schema schema = getSchema();
ForeignKey fk;
if (schema != null && schema.getSchemaGroup() != null) {
@ -537,7 +595,7 @@ public class Table
} else
fk = new ForeignKey(name, this);
if (_fkList == null)
_fkList = new ArrayList(3);
_fkList = new ArrayList<ForeignKey>(3);
_fkList.add(fk);
_fks = null;
return fk;
@ -557,7 +615,7 @@ public class Table
Schema schema = getSchema();
if (schema != null && schema.getSchemaGroup() != null)
schema.getSchemaGroup().removeName(fk.getName());
schema.getSchemaGroup().removeName(fk.getIdentifier());
_fks = null;
fk.remove();
return true;
@ -570,7 +628,7 @@ public class Table
if (fk == null)
return null;
ForeignKey copy = addForeignKey(fk.getName());
ForeignKey copy = addForeignKey(fk.getIdentifier());
copy.setDeleteAction(fk.getDeleteAction());
Schema schema = getSchema();
@ -582,12 +640,12 @@ public class Table
Column[] cols = fk.getColumns();
for (int i = 0; i < cols.length; i++)
copy.join(getColumn(cols[i].getName()),
joined.getColumn(pks[i].getName()));
copy.join(getColumn(cols[i].getIdentifier()),
joined.getColumn(pks[i].getIdentifier()));
cols = fk.getConstantColumns();
for (int i = 0; i < cols.length; i++)
copy.joinConstant(getColumn(cols[i].getName()),
copy.joinConstant(getColumn(cols[i].getIdentifier()),
fk.getPrimaryKeyConstant(cols[i]));
pks = fk.getConstantPrimaryKeyColumns();
@ -595,7 +653,7 @@ public class Table
joined = schema.getSchemaGroup().findTable(pks[0].getTable());
for (int i = 0; i < pks.length; i++)
copy.joinConstant(fk.getConstant(pks[i]),
joined.getColumn(pks[i].getName()));
joined.getColumn(pks[i].getIdentifier()));
}
return copy;
}
@ -612,17 +670,31 @@ public class Table
/**
* Return the index with the given name, or null if none.
* @deprecated
*/
public Index getIndex(String name) {
if (name == null || _idxMap == null)
return null;
return (Index) _idxMap.get(name.toUpperCase());
return getIndex(DBIdentifier.newIdentifier(name, DBIdentifierType.INDEX, true));
}
public Index getIndex(DBIdentifier name) {
if (name == null || _idxMap == null)
return null;
DBIdentifier sName = DBIdentifier.toUpper(name);
return (Index) _idxMap.get(sName);
}
/**
* Add an index to the table.
* @deprecated
*/
public Index addIndex(String name) {
return addIndex(DBIdentifier.newIndex(name));
}
public Index addIndex(DBIdentifier name) {
Schema schema = getSchema();
Index idx;
if (schema != null && schema.getSchemaGroup() != null) {
@ -631,8 +703,9 @@ public class Table
} else
idx = new Index(name, this);
if (_idxMap == null)
_idxMap = new TreeMap();
_idxMap.put(name.toUpperCase(), idx);
_idxMap = new TreeMap<DBIdentifier, Index>();
DBIdentifier sName = DBIdentifier.toUpper(name);
_idxMap.put(sName, idx);
_idxs = null;
return idx;
}
@ -646,14 +719,15 @@ public class Table
if (idx == null || _idxMap == null)
return false;
Index cur = (Index) _idxMap.get(idx.getName().toUpperCase());
DBIdentifier sName = DBIdentifier.toUpper(idx.getIdentifier());
Index cur = (Index) _idxMap.get(sName);
if (!idx.equals(cur))
return false;
_idxMap.remove(idx.getName().toUpperCase());
_idxMap.remove(sName);
Schema schema = getSchema();
if (schema != null && schema.getSchemaGroup() != null)
schema.getSchemaGroup().removeName(idx.getName());
schema.getSchemaGroup().removeName(idx.getIdentifier());
idx.remove();
_idxs = null;
return true;
@ -666,12 +740,12 @@ public class Table
if (idx == null)
return null;
Index copy = addIndex(idx.getName());
Index copy = addIndex(idx.getIdentifier());
copy.setUnique(idx.isUnique());
Column[] cols = idx.getColumns();
for (int i = 0; i < cols.length; i++)
copy.addColumn(getColumn(cols[i].getName()));
copy.addColumn(getColumn(cols[i].getIdentifier()));
return copy;
}
@ -687,19 +761,29 @@ public class Table
/**
* Return the unique constraint with the given name, or null if none.
* @deprecated
*/
public Unique getUnique(String name) {
return getUnique(DBIdentifier.newConstraint(name));
}
public Unique getUnique(DBIdentifier name) {
Unique[] unqs = getUniques();
for (int i = 0; i < unqs.length; i++)
if (StringUtils.equalsIgnoreCase(name, unqs[i].getName()))
if (DBIdentifier.equal(name, unqs[i].getIdentifier()))
return unqs[i];
return null;
}
/**
* Add a unique constraint to the table.
* @deprecated
*/
public Unique addUnique(String name) {
return addUnique(DBIdentifier.newConstraint(name));
}
public Unique addUnique(DBIdentifier name) {
Schema schema = getSchema();
Unique unq;
if (schema != null && schema.getSchemaGroup() != null) {
@ -708,7 +792,7 @@ public class Table
} else
unq = new Unique(name, this);
if (_unqList == null)
_unqList = new ArrayList(3);
_unqList = new ArrayList<Unique>(3);
_unqList.add(unq);
_unqs = null;
return unq;
@ -728,7 +812,7 @@ public class Table
Schema schema = getSchema();
if (schema != null && schema.getSchemaGroup() != null)
schema.getSchemaGroup().removeName(unq.getName());
schema.getSchemaGroup().removeName(unq.getIdentifier());
_unqs = null;
unq.remove();
return true;
@ -741,12 +825,12 @@ public class Table
if (unq == null)
return null;
Unique copy = addUnique(unq.getName());
Unique copy = addUnique(unq.getIdentifier());
copy.setDeferred(unq.isDeferred());
Column[] cols = unq.getColumns();
for (int i = 0; i < cols.length; i++)
copy.addColumn(getColumn(cols[i].getName()));
copy.addColumn(getColumn(cols[i].getIdentifier()));
return copy;
}
@ -781,23 +865,23 @@ public class Table
}
public int compareTo(Object other) {
String name = getFullName();
String otherName = ((Table) other).getFullName();
if (name == null && otherName == null)
DBIdentifier name = getFullIdentifier();
DBIdentifier otherName = ((Table) other).getFullIdentifier();
if (DBIdentifier.isNull(name) && DBIdentifier.isNull(otherName))
return 0;
if (name == null)
if (DBIdentifier.isNull(name))
return 1;
if (otherName == null)
if (DBIdentifier.isNull(otherName))
return -1;
return name.compareTo(otherName);
}
public String toString() {
return getFullName();
return getFullIdentifier().getName();
}
public boolean hasComment() {
return _comment != null && !_comment.equalsIgnoreCase(_name);
return _comment != null && !_comment.equalsIgnoreCase(_name.getName());
}
public String getComment() {

View File

@ -30,6 +30,9 @@ import java.sql.Types;
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
import org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl;
import org.apache.openjpa.jdbc.identifier.Normalizer;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.identifier.QualifiedDBIdentifier;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.jdbc.sql.SQLBuffer;
import org.apache.openjpa.jdbc.sql.SQLExceptions;
@ -37,6 +40,7 @@ import org.apache.openjpa.lib.conf.Configurable;
import org.apache.openjpa.lib.conf.Configuration;
import org.apache.openjpa.lib.conf.Configurations;
import org.apache.openjpa.lib.log.Log;
import org.apache.openjpa.lib.meta.MetaDataSerializer;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.lib.util.Options;
import org.apache.openjpa.meta.JavaTypes;
@ -62,9 +66,9 @@ public class TableSchemaFactory
private JDBCConfiguration _conf = null;
private Log _log = null;
private String _table = "OPENJPA_SCHEMA";
private String _pkColumnName = "ID";
private String _schemaColumnName = "SCHEMA_DEF";
private DBIdentifier _table = DBIdentifier.newTable("OPENJPA_SCHEMA");
private DBIdentifier _pkColumnName = DBIdentifier.newColumn("ID");
private DBIdentifier _schemaColumnName = DBIdentifier.newColumn("SCHEMA_DEF");
private Column _pkColumn = null;
private Column _schemaColumn = null;
@ -73,7 +77,7 @@ public class TableSchemaFactory
* <code>OPENJPA_SCHEMA</code>.
*/
public String getTable() {
return _table;
return _table.getName();
}
/**
@ -81,7 +85,7 @@ public class TableSchemaFactory
* <code>OPENJPA_SCHEMA</code>.
*/
public void setTable(String name) {
_table = name;
_table = DBIdentifier.newTable(name);
}
/**
@ -97,7 +101,7 @@ public class TableSchemaFactory
* Defaults to <code>ID</code>.
*/
public void setPrimaryKeyColumn(String name) {
_pkColumnName = name;
_pkColumnName = DBIdentifier.newColumn(name);
}
/**
@ -105,7 +109,7 @@ public class TableSchemaFactory
* Defaults to <code>ID</code>.
*/
public String getPrimaryKeyColumn() {
return _pkColumnName;
return _pkColumnName.getName();
}
/**
@ -113,7 +117,7 @@ public class TableSchemaFactory
* Defaults to <code>SCHEMA_DEF</code>.
*/
public void setSchemaColumn(String name) {
_schemaColumnName = name;
_schemaColumnName = DBIdentifier.newColumn(name);
}
/**
@ -121,7 +125,7 @@ public class TableSchemaFactory
* Defaults to <code>SCHEMA_DEF</code>.
*/
public String getSchemaColumn() {
return _schemaColumnName;
return _schemaColumnName.getName();
}
public JDBCConfiguration getConfiguration() {
@ -139,7 +143,7 @@ public class TableSchemaFactory
public void endConfiguration() {
buildTable();
}
public synchronized SchemaGroup readSchema() {
String schema = null;
try {
@ -154,7 +158,7 @@ public class TableSchemaFactory
XMLSchemaParser parser = new XMLSchemaParser(_conf);
try {
parser.parse(new StringReader(schema),
_schemaColumn.getFullName());
_schemaColumn.getQualifiedPath().toString());
} catch (IOException ioe) {
throw new GeneralException(ioe);
}
@ -166,7 +170,7 @@ public class TableSchemaFactory
ser.addAll(schema);
Writer writer = new StringWriter();
try {
ser.serialize(writer, ser.COMPACT);
ser.serialize(writer, MetaDataSerializer.COMPACT);
} catch (IOException ioe) {
throw new GeneralException(ioe);
}
@ -232,7 +236,8 @@ public class TableSchemaFactory
DBDictionary dict = _conf.getDBDictionaryInstance();
stmnt = conn.prepareStatement("INSERT INTO "
+ dict.getFullName(_pkColumn.getTable(), false)
+ " (" + _pkColumn + ", " + _schemaColumn + ") VALUES (?, ?)");
+ " (" + dict.getColumnDBName(_pkColumn) + ", " +
dict.getColumnDBName(_schemaColumn) + ") VALUES (?, ?)");
dict.setInt(stmnt, 1, 1, _pkColumn);
dict.setNull(stmnt, 2, _schemaColumn.getType(), _schemaColumn);
dict.setTimeouts(stmnt, _conf, true);
@ -328,11 +333,12 @@ public class TableSchemaFactory
String update;
if (embedded)
update = "UPDATE " + dict.getFullName(_pkColumn.getTable(), false)
+ " SET " + _schemaColumn + " = ? WHERE " + _pkColumn + " = ?";
+ " SET " + dict.getColumnDBName(_schemaColumn) + " = ? WHERE " +
dict.getColumnIdentifier(_pkColumn) + " = ?";
else
update = "SELECT " + _schemaColumn + " FROM "
update = "SELECT " + dict.getColumnDBName(_schemaColumn) + " FROM "
+ dict.getFullName(_pkColumn.getTable(), false)
+ " WHERE " + _pkColumn + " = ?";
+ " WHERE " + dict.getColumnDBName(_pkColumn) + " = ?";
Connection conn = getConnection();
PreparedStatement stmnt = null;
@ -392,10 +398,11 @@ public class TableSchemaFactory
* Creates the object-level representation of the sequence table.
*/
private void buildTable() {
String tableName = Strings.getClassName(_table);
String schemaName = Strings.getPackageName(_table);
if (schemaName.length() == 0)
schemaName = Schemas.getNewTableSchema(_conf);
QualifiedDBIdentifier path = QualifiedDBIdentifier.getPath(_table);
DBIdentifier tableName = path.getIdentifier();
DBIdentifier schemaName = path.getSchemaName();
if (DBIdentifier.isEmpty(schemaName))
schemaName = Schemas.getNewTableSchemaIdentifier(_conf);
// build the table in one of the designated schemas
SchemaGroup group = new SchemaGroup();

View File

@ -18,12 +18,15 @@
*/
package org.apache.openjpa.jdbc.schema;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
/**
* Represents a unique constraint. It can also represent a partial constraint.
*
* @author Abe White
* @author Pinaki Poddar
*/
@SuppressWarnings("serial")
public class Unique
extends LocalConstraint {
@ -36,11 +39,16 @@ public class Unique
*
* @param name the name of the constraint, if any
* @param table the table of the constraint
* @deprecated
*/
public Unique(String name, Table table) {
super(name, table);
}
public Unique(DBIdentifier name, Table table) {
super(name, table);
}
public boolean isLogical() {
return false;
}
@ -59,10 +67,15 @@ public class Unique
/**
* Set the name of the constraint. This method cannot be called if the
* constraint already belongs to a table.
* @deprecated
*/
public void setName(String name) {
super.setName(name);
}
public void setIdentifier(DBIdentifier name) {
super.setIdentifier(name);
}
/**
* Return true if the structure of this primary key matches that of

View File

@ -30,6 +30,7 @@ import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.lib.meta.SourceTracker;
import org.apache.openjpa.lib.meta.XMLMetaDataParser;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.lib.util.Localizer.Message;
@ -115,10 +116,10 @@ public class XMLSchemaParser
private boolean _delay = false;
// used to collect info on schema elements before they're resolved
private final Collection _pkInfos = new LinkedList();
private final Collection _indexInfos = new LinkedList();
private final Collection _unqInfos = new LinkedList();
private final Collection _fkInfos = new LinkedList();
private final Collection<PrimaryKeyInfo> _pkInfos = new LinkedList<PrimaryKeyInfo>();
private final Collection<IndexInfo> _indexInfos = new LinkedList<IndexInfo>();
private final Collection<UniqueInfo> _unqInfos = new LinkedList<UniqueInfo>();
private final Collection<ForeignKeyInfo> _fkInfos = new LinkedList<ForeignKeyInfo>();
/**
* Constructor. Supply configuration.
@ -185,11 +186,11 @@ public class XMLSchemaParser
PrimaryKeyInfo pkInfo;
String colName;
Column col;
for (Iterator itr = _pkInfos.iterator(); itr.hasNext();) {
pkInfo = (PrimaryKeyInfo) itr.next();
for (Iterator cols = pkInfo.cols.iterator(); cols.hasNext();) {
colName = (String) cols.next();
col = pkInfo.pk.getTable().getColumn(colName, _dict);
for (Iterator<PrimaryKeyInfo> itr = _pkInfos.iterator(); itr.hasNext();) {
pkInfo = itr.next();
for (Iterator<String> cols = pkInfo.cols.iterator(); cols.hasNext();) {
colName = cols.next();
col = pkInfo.pk.getTable().getColumn(colName);
if (col == null)
throwUserException(_loc.get("pk-resolve", new Object[]
{ colName, pkInfo.pk.getTable() }));
@ -206,11 +207,11 @@ public class XMLSchemaParser
IndexInfo indexInfo;
String colName;
Column col;
for (Iterator itr = _indexInfos.iterator(); itr.hasNext();) {
indexInfo = (IndexInfo) itr.next();
for (Iterator cols = indexInfo.cols.iterator(); cols.hasNext();) {
colName = (String) cols.next();
col = indexInfo.index.getTable().getColumn(colName, _dict);
for (Iterator<IndexInfo> itr = _indexInfos.iterator(); itr.hasNext();) {
indexInfo = itr.next();
for (Iterator<String> cols = indexInfo.cols.iterator(); cols.hasNext();) {
colName = cols.next();
col = indexInfo.index.getTable().getColumn(colName);
if (col == null)
throwUserException(_loc.get("index-resolve", new Object[]
{ indexInfo.index, colName,
@ -232,10 +233,10 @@ public class XMLSchemaParser
Column pkCol;
String pkColName;
PrimaryKey pk;
Iterator pks;
Iterator cols;
for (Iterator itr = _fkInfos.iterator(); itr.hasNext();) {
fkInfo = (ForeignKeyInfo) itr.next();
Iterator<String> pks;
Iterator<String> cols;
for (Iterator<ForeignKeyInfo> itr = _fkInfos.iterator(); itr.hasNext();) {
fkInfo = itr.next();
toTable = _group.findTable(fkInfo.toTable);
if (toTable == null || toTable.getPrimaryKey() == null)
throwUserException(_loc.get("fk-totable", new Object[]
@ -250,13 +251,13 @@ public class XMLSchemaParser
pks = fkInfo.pks.iterator();
for (cols = fkInfo.cols.iterator(); cols.hasNext();) {
colName = (String) cols.next();
col = fkInfo.fk.getTable().getColumn(colName, _dict);
col = fkInfo.fk.getTable().getColumn(colName);
if (col == null)
throwUserException(_loc.get("fk-nocol",
fkInfo.fk, colName, fkInfo.fk.getTable()));
pkColName = (String) pks.next();
pkCol = toTable.getColumn(pkColName, _dict);
pkCol = toTable.getColumn(pkColName);
if (pkCol == null)
throwUserException(_loc.get("fk-nopkcol", new Object[]
{ fkInfo.fk, pkColName, toTable,
@ -267,9 +268,9 @@ public class XMLSchemaParser
// make constant joins
cols = fkInfo.constCols.iterator();
for (Iterator vals = fkInfo.consts.iterator(); vals.hasNext();) {
colName = (String) cols.next();
col = fkInfo.fk.getTable().getColumn(colName, _dict);
for (Iterator<Object> vals = fkInfo.consts.iterator(); vals.hasNext();) {
colName = cols.next();
col = fkInfo.fk.getTable().getColumn(colName);
if (col == null)
throwUserException(_loc.get("fk-nocol",
fkInfo.fk, colName, fkInfo.fk.getTable()));
@ -278,9 +279,9 @@ public class XMLSchemaParser
}
pks = fkInfo.constColsPK.iterator();
for (Iterator vals = fkInfo.constsPK.iterator(); vals.hasNext();) {
pkColName = (String) pks.next();
pkCol = toTable.getColumn(pkColName, _dict);
for (Iterator<Object> vals = fkInfo.constsPK.iterator(); vals.hasNext();) {
pkColName = pks.next();
pkCol = toTable.getColumn(pkColName);
if (pkCol == null)
throwUserException(_loc.get("fk-nopkcol", new Object[]
{ fkInfo.fk, pkColName, toTable,
@ -299,11 +300,11 @@ public class XMLSchemaParser
UniqueInfo unqInfo;
String colName;
Column col;
for (Iterator itr = _unqInfos.iterator(); itr.hasNext();) {
unqInfo = (UniqueInfo) itr.next();
for (Iterator cols = unqInfo.cols.iterator(); cols.hasNext();) {
for (Iterator<UniqueInfo> itr = _unqInfos.iterator(); itr.hasNext();) {
unqInfo = itr.next();
for (Iterator<String> cols = unqInfo.cols.iterator(); cols.hasNext();) {
colName = (String) cols.next();
col = unqInfo.unq.getTable().getColumn(colName, _dict);
col = unqInfo.unq.getTable().getColumn(colName);
if (col == null)
throwUserException(_loc.get("unq-resolve", new Object[]
{ unqInfo.unq, colName, unqInfo.unq.getTable() }));
@ -412,7 +413,7 @@ public class XMLSchemaParser
seq.setLineNumber(Numbers.valueOf(locator.getLineNumber()));
seq.setColNumber(Numbers.valueOf(locator.getColumnNumber()));
}
seq.setSource(getSourceFile(), seq.SRC_XML);
seq.setSource(getSourceFile(), SourceTracker.SRC_XML);
try {
String val = attrs.getValue("initial-value");
if (val != null)
@ -430,7 +431,7 @@ public class XMLSchemaParser
private void startTable(Attributes attrs) {
_table = _schema.addTable(attrs.getValue("name"));
_table.setSource(getSourceFile(), _table.SRC_XML);
_table.setSource(getSourceFile(), SourceTracker.SRC_XML);
Locator locator = getLocation().getLocator();
if (locator != null) {
_table.setLineNumber(Numbers.valueOf(locator.getLineNumber()));
@ -580,7 +581,7 @@ public class XMLSchemaParser
private static class PrimaryKeyInfo {
public PrimaryKey pk = null;
public Collection cols = new LinkedList();
public Collection<String> cols = new LinkedList<String>();
}
/**
@ -589,7 +590,7 @@ public class XMLSchemaParser
private static class IndexInfo {
public Index index = null;
public Collection cols = new LinkedList();
public Collection<String> cols = new LinkedList<String>();
}
/**
@ -598,7 +599,7 @@ public class XMLSchemaParser
public static class UniqueInfo {
public Unique unq = null;
public Collection cols = new LinkedList();
public Collection<String> cols = new LinkedList<String>();
}
/**
@ -608,11 +609,11 @@ public class XMLSchemaParser
public ForeignKey fk = null;
public String toTable = null;
public Collection cols = new LinkedList();
public Collection pks = new LinkedList();
public Collection consts = new LinkedList();
public Collection constCols = new LinkedList();
public Collection constsPK = new LinkedList();
public Collection constColsPK = new LinkedList();
public Collection<String> cols = new LinkedList<String>();
public Collection<String> pks = new LinkedList<String>();
public Collection<Object> consts = new LinkedList<Object>();
public Collection<String> constCols = new LinkedList<String>();
public Collection<Object> constsPK = new LinkedList<Object>();
public Collection<String> constColsPK = new LinkedList<String>();
}
}

View File

@ -50,8 +50,8 @@ public class XMLSchemaSerializer
private static final Localizer _loc = Localizer.forPackage
(XMLSchemaSerializer.class);
private final Collection _tables = new TreeSet();
private final Collection _seqs = new TreeSet();
private final Collection<Table> _tables = new TreeSet<Table>();
private final Collection<Sequence> _seqs = new TreeSet<Sequence>();
/**
* Constructor. Supply configuration.
@ -140,7 +140,7 @@ public class XMLSchemaSerializer
return _tables;
if (_tables.isEmpty())
return _seqs;
List all = new ArrayList(_seqs.size() + _tables.size());
List<Object> all = new ArrayList<Object>(_seqs.size() + _tables.size());
all.addAll(_seqs);
all.addAll(_tables);
return all;
@ -180,7 +180,7 @@ public class XMLSchemaSerializer
/**
* Serializes the given objects together into the current schema.
*/
private void serializeSchema(String name, Collection objs)
private void serializeSchema(String name, Collection<?> objs)
throws SAXException {
if (objs.isEmpty())
return;
@ -194,7 +194,7 @@ public class XMLSchemaSerializer
// tables and seqs
Object obj;
for (Iterator itr = objs.iterator(); itr.hasNext();) {
for (Iterator<?> itr = objs.iterator(); itr.hasNext();) {
obj = itr.next();
if (obj instanceof Table)
serializeTable((Table) obj);

View File

@ -25,6 +25,7 @@ import java.sql.SQLException;
import java.sql.Types;
import java.util.Arrays;
import org.apache.openjpa.jdbc.identifier.DBIdentifier.DBIdentifierType;
import org.apache.openjpa.jdbc.kernel.exps.FilterValue;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.Index;
@ -93,7 +94,8 @@ public abstract class AbstractSQLServerDictionary
}
public String getFullName(Index idx) {
return getFullName(idx.getTable(), false) + "." + idx.getName();
return toDBName(getNamingUtil().append(DBIdentifierType.INDEX,
getFullIdentifier(idx.getTable(), false),idx.getIdentifier()));
}
public void setNull(PreparedStatement stmnt, int idx, int colType,

View File

@ -65,7 +65,11 @@ public class AccessDictionary
maxIndexesPerTable = 32;
substringFunctionName = "MID";
}
setLeadingDelimiter("[");
setTrailingDelimiter("]");
}
public void setLong(PreparedStatement stmnt, int idx, long val, Column col)
throws SQLException {

View File

@ -29,10 +29,10 @@ import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.Set;
import java.util.StringTokenizer;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
import org.apache.openjpa.jdbc.kernel.exps.FilterValue;
import org.apache.openjpa.jdbc.kernel.exps.Lit;
@ -230,17 +230,24 @@ public class DB2Dictionary
return sql;
}
@Override
protected String getSequencesSQL(String schemaName, String sequenceName) {
return getSequencesSQL(DBIdentifier.newSchema(schemaName),
DBIdentifier.newSequence(sequenceName));
}
@Override
protected String getSequencesSQL(DBIdentifier schemaName, DBIdentifier sequenceName) {
StringBuilder buf = new StringBuilder();
buf.append(sequenceSQL);
if (schemaName != null || sequenceName != null)
if (!DBIdentifier.isNull(schemaName) || !DBIdentifier.isNull(sequenceName))
buf.append(" WHERE ");
if (schemaName != null) {
if (!DBIdentifier.isNull(schemaName)) {
buf.append(sequenceSchemaSQL);
if (sequenceName != null)
if (!DBIdentifier.isNull(sequenceName))
buf.append(" AND ");
}
if (sequenceName != null)
if (!DBIdentifier.isNull(sequenceName))
buf.append(sequenceNameSQL);
return buf.toString();
}
@ -381,7 +388,7 @@ public class DB2Dictionary
int isolationLevel;
// For db2UDBV81OrEarlier and db2ISeriesV5R3OrEarlier:
// "optimize for" clause appears before "for update" clause.
StringBuilder forUpdateString = new StringBuilder(getOptimizeClause(sel));
StringBuffer forUpdateString = new StringBuffer(getOptimizeClause(sel));
// Determine the isolationLevel; the fetch
// configuration data overrides the persistence.xml value
if (fetch != null && fetch.getIsolation() != -1)
@ -889,12 +896,18 @@ public class DB2Dictionary
* Create an index if necessary for some database tables
*/
public void createIndexIfNecessary(Schema schema, String table,
Column pkColumn) {
createIndexIfNecessary(schema, DBIdentifier.newTable(table),
pkColumn);
}
public void createIndexIfNecessary(Schema schema, DBIdentifier table,
Column pkColumn) {
if (isDB2ZOSV8xOrLater()) {
// build the index for the sequence tables
// the index name will be the fully qualified table name + _IDX
Table tab = schema.getTable(table);
Index idx = tab.addIndex(tab.getFullName() + "_IDX");
Index idx = tab.addIndex(DBIdentifier.append(tab.getFullIdentifier(), "IDX"));
idx.setUnique(true);
idx.addColumn(pkColumn);
}
@ -961,7 +974,8 @@ public class DB2Dictionary
// for DB2, if the column was defined as CHAR for BIT DATA, then
// we want to use the setBytes in stead of the setBinaryStream
if (useSetBytesForBlobs
|| (col.getTypeName() != null && col.getTypeName().contains("BIT DATA"))) {
|| (!DBIdentifier.isNull(col.getTypeIdentifier()) &&
col.getTypeIdentifier().getName().contains("BIT DATA"))) {
stmnt.setBytes(idx, val);
} else {
setBinaryStream(stmnt, idx, new ByteArrayInputStream(val), val.length, col);

View File

@ -135,7 +135,8 @@ public class EmpressDictionary
// empress wants dropped columns in the form: ALTER TABLE foo
// DELETE columnToDrop
return new String[]{ "ALTER TABLE "
+ getFullName(column.getTable(), false) + " DELETE " + column };
+ getFullName(column.getTable(), false) + " DELETE " +
getColumnDBName(column) };
}
public void setFloat(PreparedStatement stmnt, int idx, float val,

View File

@ -29,12 +29,14 @@ import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
import org.apache.openjpa.jdbc.kernel.exps.FilterValue;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.ForeignKey;
import org.apache.openjpa.jdbc.schema.Index;
import org.apache.openjpa.jdbc.schema.Sequence;
import org.apache.openjpa.jdbc.schema.Unique;
import org.apache.openjpa.lib.identifier.IdentifierUtil;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.util.UnsupportedException;
@ -285,8 +287,15 @@ public class FirebirdDictionary
*/
@Override
protected String getTableNameForMetadata(String tableName) {
return (tableName == null) ? "%" : super
.getTableNameForMetadata(tableName);
return (tableName == null) ? IdentifierUtil.PERCENT :
getTableNameForMetadata(DBIdentifier.newTable(tableName));
}
protected String getTableNameForMetadata(DBIdentifier tableName) {
if (DBIdentifier.isNull(tableName)) {
return IdentifierUtil.PERCENT;
}
return super.getTableNameForMetadata(tableName);
}
/**
@ -306,7 +315,7 @@ public class FirebirdDictionary
@Override
public String[] getDropColumnSQL(Column column) {
return new String[] { "ALTER TABLE "
+ getFullName(column.getTable(), false) + " DROP " + column };
+ getFullName(column.getTable(), false) + " DROP " + getColumnDBName(column) };
}
/**
@ -338,6 +347,11 @@ public class FirebirdDictionary
*/
@Override
protected String getSequencesSQL(String schemaName, String sequenceName) {
return getSequencesSQL(DBIdentifier.newSchema(schemaName), DBIdentifier.newSequence(sequenceName));
}
@Override
protected String getSequencesSQL(DBIdentifier schemaName, DBIdentifier sequenceName) {
StringBuilder buf = new StringBuilder(sequenceSQL);
if (sequenceName != null)
buf.append(sequenceNameSQL);
@ -354,7 +368,7 @@ public class FirebirdDictionary
@Override
protected Sequence newSequence(ResultSet sequenceMeta) throws SQLException {
Sequence seq = super.newSequence(sequenceMeta);
seq.setName(seq.getName().trim());
seq.setIdentifier(DBIdentifier.trim(seq.getIdentifier()));
return seq;
}

Some files were not shown because too many files have changed in this diff Show More