Search in sources :

Example 1 with ColumnDefinitionException

use of org.datanucleus.store.rdbms.exceptions.ColumnDefinitionException in project datanucleus-rdbms by datanucleus.

the class ColumnImpl method getSQLDefinition.

/* (non-Javadoc)
     * @see org.datanucleus.store.rdbms.table.Column#getSQLDefinition()
     */
public String getSQLDefinition() {
    StringBuilder def = new StringBuilder(identifier.toString());
    if (!StringUtils.isWhitespace(columnMetaData.getColumnDdl())) {
        // User-defined DDL, so assume they set the type etc to something sensible
        // Note that the JPA spec doesn't explicitly specify if this has to include the type or not
        def.append(" ").append(columnMetaData.getColumnDdl());
        return def.toString();
    }
    DatastoreAdapter adapter = getStoreManager().getDatastoreAdapter();
    // Add any type specification.
    if (adapter.supportsOption(DatastoreAdapter.IDENTITY_COLUMNS) && isIdentity() && !adapter.supportsOption(DatastoreAdapter.AUTO_INCREMENT_COLUMN_TYPE_SPECIFICATION)) {
    // Don't add type
    } else if (typeName != null) {
        // Allow for manual override of "type" for things like MySQL ENUM where we want to define the type with its options
        def.append(" " + typeName);
    } else {
        StringBuilder typeSpec = new StringBuilder(typeInfo.getTypeName());
        // 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("]")) {
                    // skip
                    continue;
                }
                typeSpec.append(" " + tok);
            }
        }
        // Add any precision. We use the "allowsPrecisionSpec" flag for this
        StringBuilder precSpec = new StringBuilder();
        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) {
            // 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 ColumnDefinitionException(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(DatastoreAdapter.DEFAULT_BEFORE_NULL_IN_COLUMN_OPTIONS) && adapter.supportsOption(DatastoreAdapter.DEFAULT_KEYWORD_IN_COLUMN_OPTIONS) && columnMetaData.getDefaultValue() != null) {
        def.append(" ").append(getDefaultDefinition());
    }
    if (isIdentity() && isPrimaryKey() && adapter.supportsOption(DatastoreAdapter.AUTO_INCREMENT_PK_IN_CREATE_TABLE_COLUMN_DEF)) {
        def.append(" PRIMARY KEY");
    }
    // Nullability
    if (adapter.supportsOption(DatastoreAdapter.IDENTITY_COLUMNS) && isIdentity() && !adapter.supportsOption(DatastoreAdapter.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(DatastoreAdapter.DEFAULT_KEYWORD_WITH_NOT_NULL_IN_COLUMN_OPTIONS)) {
                def.append(" NOT NULL");
            }
        } else if (typeInfo.getNullable() == DatabaseMetaData.columnNullable) {
            if (adapter.supportsOption(DatastoreAdapter.NULLS_KEYWORD_IN_COLUMN_OPTIONS)) {
                def.append(" NULL");
            }
        }
    }
    // Add DEFAULT (if specifiable after NULL)
    if (!adapter.supportsOption(DatastoreAdapter.DEFAULT_BEFORE_NULL_IN_COLUMN_OPTIONS) && adapter.supportsOption(DatastoreAdapter.DEFAULT_KEYWORD_IN_COLUMN_OPTIONS) && columnMetaData.getDefaultValue() != null) {
        def.append(" ").append(getDefaultDefinition());
    }
    // CHECK Constraints
    if (adapter.supportsOption(DatastoreAdapter.CHECK_IN_CREATE_STATEMENTS) && checkConstraints != null) {
        def.append(" " + checkConstraints.toString());
    }
    // Auto Increment
    if (adapter.supportsOption(DatastoreAdapter.IDENTITY_COLUMNS) && isIdentity()) {
        def.append(" " + adapter.getAutoIncrementKeyword());
    }
    // Uniqueness
    if (isUnique() && !adapter.supportsOption(DatastoreAdapter.UNIQUE_IN_END_CREATE_STATEMENTS)) {
        def.append(" UNIQUE");
    }
    return def.toString();
}
Also used : StringTokenizer(java.util.StringTokenizer) ColumnDefinitionException(org.datanucleus.store.rdbms.exceptions.ColumnDefinitionException) DatastoreAdapter(org.datanucleus.store.rdbms.adapter.DatastoreAdapter)

Aggregations

StringTokenizer (java.util.StringTokenizer)1 DatastoreAdapter (org.datanucleus.store.rdbms.adapter.DatastoreAdapter)1 ColumnDefinitionException (org.datanucleus.store.rdbms.exceptions.ColumnDefinitionException)1