def.append(" ").append(columnMetaData.getColumnDdl());
return def.toString();
}
StringBuffer typeSpec = new StringBuffer(typeInfo.getTypeName());
RDBMSAdapter adapter = (RDBMSAdapter)getStoreManager().getDatastoreAdapter();
// Add type specification.
boolean specifyType = true;
if (adapter.supportsOption(DatastoreAdapter.IDENTITY_COLUMNS) && isIdentity() &&
!adapter.supportsOption(RDBMSAdapter.AUTO_INCREMENT_COLUMN_TYPE_SPECIFICATION))
{
specifyType = false;
}
if (specifyType)
{
// Parse and append createParams to the typeName if it looks like it's supposed to be appended,
// i.e. if it contains parentheses, and the type name itself doesn't. createParams is mighty
// ill-defined by the JDBC spec, but attempt to interpret it.
if (typeInfo.getCreateParams() != null && typeInfo.getCreateParams().indexOf('(') >= 0 &&
typeInfo.getTypeName().indexOf('(') < 0)
{
StringTokenizer toks = new StringTokenizer(typeInfo.getCreateParams());
while (toks.hasMoreTokens())
{
String tok = toks.nextToken();
if (tok.startsWith("[") && tok.endsWith("]"))
{
// The brackets look like they indicate an optional param so
// skip
continue;
}
typeSpec.append(" " + tok);
}
}
// Add any precision - note that there is no obvious flag in the JDBC typeinfo to
// tell us whether the type allows this specification or not, and many JDBC just
// return crap anyway. We use the allowsPrecisionSpec flag for this
StringBuffer precSpec = new StringBuffer();
int sqlPrecision = getSQLPrecision();
if (sqlPrecision > 0 && typeInfo.isAllowsPrecisionSpec())
{
precSpec.append(sqlPrecision);
if (columnMetaData.getScale() != null)
{
precSpec.append("," + columnMetaData.getScale());
}
}
else if (sqlPrecision > 0 && !typeInfo.isAllowsPrecisionSpec())
{
NucleusLogger.DATASTORE_SCHEMA.warn(LOCALISER.msg("020183", this.toString()));
}
int lParenIdx = typeSpec.toString().indexOf('(');
int rParenIdx = typeSpec.toString().indexOf(')', lParenIdx);
if (lParenIdx > 0 && rParenIdx > 0)
{
// Some databases (like DB2) give you typeNames with ()'s already
// present ready for you to insert the values instead of appending them.
if (precSpec.length() > 0)
{
typeSpec.replace(lParenIdx + 1, rParenIdx, precSpec.toString());
}
else if (rParenIdx == lParenIdx + 1)
{
throw new DatastoreFieldDefinitionException(LOCALISER.msg("020184", this.toString()));
}
}
else if (precSpec.length() > 0)
{
typeSpec.append('(');
typeSpec.append(precSpec.toString());
typeSpec.append(')');
}
def.append(" " + typeSpec.toString());
}
// Add DEFAULT (if specifiable before NULL)
if (adapter.supportsOption(RDBMSAdapter.DEFAULT_BEFORE_NULL_IN_COLUMN_OPTIONS) &&
adapter.supportsOption(RDBMSAdapter.DEFAULT_KEYWORD_IN_COLUMN_OPTIONS) &&
columnMetaData.getDefaultValue() != null)
{
def.append(" ").append(getDefaultDefinition());
}
// Nullability
if (adapter.supportsOption(DatastoreAdapter.IDENTITY_COLUMNS) && isIdentity() &&
!adapter.supportsOption(RDBMSAdapter.AUTO_INCREMENT_KEYS_NULL_SPECIFICATION))
{
// Do nothing since the adapter doesn't allow NULL specifications with autoincrement/identity
}
else
{
if (!isNullable())
{
if (columnMetaData.getDefaultValue() == null ||
adapter.supportsOption(RDBMSAdapter.DEFAULT_KEYWORD_WITH_NOT_NULL_IN_COLUMN_OPTIONS))
{
def.append(" NOT NULL");
}
}
else if (typeInfo.getNullable() == DatabaseMetaData.columnNullable)
{
if (adapter.supportsOption(RDBMSAdapter.NULLS_KEYWORD_IN_COLUMN_OPTIONS))
{
def.append(" NULL");
}
}
}
// Add DEFAULT (if specifiable after NULL)
if (!adapter.supportsOption(RDBMSAdapter.DEFAULT_BEFORE_NULL_IN_COLUMN_OPTIONS) &&
adapter.supportsOption(RDBMSAdapter.DEFAULT_KEYWORD_IN_COLUMN_OPTIONS) &&
columnMetaData.getDefaultValue() != null)
{
def.append(" ").append(getDefaultDefinition());
}
// Constraints checks
if (adapter.supportsOption(RDBMSAdapter.CHECK_IN_CREATE_STATEMENTS) && constraints != null)
{
def.append(" " + constraints.toString());
}
// Auto Increment
if (adapter.supportsOption(DatastoreAdapter.IDENTITY_COLUMNS) && isIdentity())
{
def.append(" " + adapter.getAutoIncrementKeyword());
}
// Uniqueness
if (isUnique() && !adapter.supportsOption(RDBMSAdapter.UNIQUE_IN_END_CREATE_STATEMENTS))
{
def.append(" UNIQUE");
}
return def.toString();