diff --git a/core/src/main/java/org/hibernate/internal/util/jdbc/TypeInfo.java b/core/src/main/java/org/hibernate/internal/util/jdbc/TypeInfo.java new file mode 100644 index 0000000000..543913df56 --- /dev/null +++ b/core/src/main/java/org/hibernate/internal/util/jdbc/TypeInfo.java @@ -0,0 +1,126 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.internal.util.jdbc; + +/** + * Models type info extracted from {@link java.sql.DatabaseMetaData#getTypeInfo()} + * + * @author Steve Ebersole + */ +public class TypeInfo { + private final String typeName; + private final int jdbcTypeCode; + private final String[] createParams; + private final boolean unsigned; + private final int precision; + private final short minimumScale; + private final short maximumScale; + private final boolean fixedPrecisionScale; + private final String literalPrefix; + private final String literalSuffix; + private final boolean caseSensitive; + private final TypeSearchability searchability; + private final TypeNullability nullability; + + public TypeInfo( + String typeName, + int jdbcTypeCode, + String[] createParams, + boolean unsigned, + int precision, + short minimumScale, + short maximumScale, + boolean fixedPrecisionScale, + String literalPrefix, + String literalSuffix, + boolean caseSensitive, + TypeSearchability searchability, + TypeNullability nullability) { + this.typeName = typeName; + this.jdbcTypeCode = jdbcTypeCode; + this.createParams = createParams; + this.unsigned = unsigned; + this.precision = precision; + this.minimumScale = minimumScale; + this.maximumScale = maximumScale; + this.fixedPrecisionScale = fixedPrecisionScale; + this.literalPrefix = literalPrefix; + this.literalSuffix = literalSuffix; + this.caseSensitive = caseSensitive; + this.searchability = searchability; + this.nullability = nullability; + } + + public String getTypeName() { + return typeName; + } + + public int getJdbcTypeCode() { + return jdbcTypeCode; + } + + public String[] getCreateParams() { + return createParams; + } + + public boolean isUnsigned() { + return unsigned; + } + + public int getPrecision() { + return precision; + } + + public short getMinimumScale() { + return minimumScale; + } + + public short getMaximumScale() { + return maximumScale; + } + + public boolean isFixedPrecisionScale() { + return fixedPrecisionScale; + } + + public String getLiteralPrefix() { + return literalPrefix; + } + + public String getLiteralSuffix() { + return literalSuffix; + } + + public boolean isCaseSensitive() { + return caseSensitive; + } + + public TypeSearchability getSearchability() { + return searchability; + } + + public TypeNullability getNullability() { + return nullability; + } +} diff --git a/core/src/main/java/org/hibernate/internal/util/jdbc/TypeInfoExtracter.java b/core/src/main/java/org/hibernate/internal/util/jdbc/TypeInfoExtracter.java new file mode 100644 index 0000000000..e39cd086eb --- /dev/null +++ b/core/src/main/java/org/hibernate/internal/util/jdbc/TypeInfoExtracter.java @@ -0,0 +1,104 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.internal.util.jdbc; + +import java.sql.DatabaseMetaData; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.LinkedHashSet; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.hibernate.util.ArrayHelper; + +/** + * Helper to extract type innformation from {@link DatabaseMetaData JDBC metadata} + * + * @author Steve Ebersole + */ +public class TypeInfoExtracter { + private static final Logger log = LoggerFactory.getLogger( TypeInfoExtracter.class ); + + private TypeInfoExtracter() { + } + + /** + * Perform the extraction + * + * @param metaData The JDBC metadata + * + * @return The extracted metadata + */ + public static LinkedHashSet extractTypeInfo(DatabaseMetaData metaData) { + LinkedHashSet typeInfoSet = new LinkedHashSet(); + try { + ResultSet resultSet = metaData.getTypeInfo(); + try { + while ( resultSet.next() ) { + typeInfoSet.add( + new TypeInfo( + resultSet.getString( "TYPE_NAME" ), + resultSet.getInt( "DATA_TYPE" ), + interpretCreateParams( resultSet.getString( "CREATE_PARAMS" ) ), + resultSet.getBoolean( "UNSIGNED_ATTRIBUTE" ), + resultSet.getInt( "PRECISION" ), + resultSet.getShort( "MINIMUM_SCALE" ), + resultSet.getShort( "MAXIMUM_SCALE" ), + resultSet.getBoolean( "FIXED_PREC_SCALE" ), + resultSet.getString( "LITERAL_PREFIX" ), + resultSet.getString( "LITERAL_SUFFIX" ), + resultSet.getBoolean( "CASE_SENSITIVE" ), + TypeSearchability.interpret( resultSet.getShort( "SEARCHABLE" ) ), + TypeNullability.interpret( resultSet.getShort( "NULLABLE" ) ) + ) + ); + } + } + catch ( SQLException e ) { + log.warn( "Error accessing type info result set : " + e.toString() ); + } + finally { + try { + resultSet.close(); + } + catch ( SQLException e ) { + log.warn( "Unable to release type info result set" ); + } + } + } + catch ( SQLException e ) { + log.warn( "Unable to retrieve type info result set : " + e.toString() ); + } + + return typeInfoSet; + } + + private static String[] interpretCreateParams(String value) { + if ( value == null || value.length() == 0 ) { + return ArrayHelper.EMPTY_STRING_ARRAY; + } + return value.split( "," ); + } +} diff --git a/core/src/main/java/org/hibernate/internal/util/jdbc/TypeNullability.java b/core/src/main/java/org/hibernate/internal/util/jdbc/TypeNullability.java new file mode 100644 index 0000000000..2dad8be345 --- /dev/null +++ b/core/src/main/java/org/hibernate/internal/util/jdbc/TypeNullability.java @@ -0,0 +1,74 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.internal.util.jdbc; + +import java.sql.DatabaseMetaData; + +/** + * Describes the instrinsic nullability of a data type as reported by the JDBC driver. + * + * @author Steve Ebersole + */ +public enum TypeNullability { + /** + * The data type can accept nulls + * @see DatabaseMetaData#typeNullable + */ + NULLABLE, + /** + * The data type cannot accept nulls + * @see DatabaseMetaData#typeNoNulls + */ + NON_NULLABLE, + /** + * It is unknown if the data type accepts nulls + * @see DatabaseMetaData#typeNullableUnknown + */ + UNKNOWN; + + /** + * Based on the code retrieved from {@link DatabaseMetaData#getTypeInfo()} for the {@code NULLABLE} + * column, return the appropriate enum. + * + * @param code The retrieved code value. + * + * @return The corresponding enum. + */ + public static TypeNullability interpret(short code) { + switch ( code ) { + case DatabaseMetaData.typeNullable: { + return NULLABLE; + } + case DatabaseMetaData.typeNoNulls: { + return NON_NULLABLE; + } + case DatabaseMetaData.typeNullableUnknown: { + return UNKNOWN; + } + default: { + throw new IllegalArgumentException( "Unknown type nullability code [" + code + "] enountered" ); + } + } + } +} diff --git a/core/src/main/java/org/hibernate/internal/util/jdbc/TypeSearchability.java b/core/src/main/java/org/hibernate/internal/util/jdbc/TypeSearchability.java new file mode 100644 index 0000000000..555524f62f --- /dev/null +++ b/core/src/main/java/org/hibernate/internal/util/jdbc/TypeSearchability.java @@ -0,0 +1,82 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.internal.util.jdbc; + +import java.sql.DatabaseMetaData; + +/** + * Describes the searchability of a data type as reported by the JDBC driver. + * + * @author Steve Ebersole + */ +public enum TypeSearchability { + /** + * Type is not searchable. + * @see java.sql.DatabaseMetaData#typePredNone + */ + NONE, + /** + * Type is fully searchable + * @see java.sql.DatabaseMetaData#typeSearchable + */ + FULL, + /** + * Type is valid only in {@code WHERE ... LIKE} + * @see java.sql.DatabaseMetaData#typePredChar + */ + CHAR, + /** + * Type is supported only in {@code WHERE ... LIKE} + * @see java.sql.DatabaseMetaData#typePredBasic + */ + BASIC; + + /** + * Based on the code retrieved from {@link java.sql.DatabaseMetaData#getTypeInfo()} for the {@code SEARCHABLE} + * column, return the appropriate enum. + * + * @param code The retrieved code value. + * + * @return The corresponding enum. + */ + public static TypeSearchability interpret(short code) { + switch ( code ) { + case DatabaseMetaData.typeSearchable: { + return FULL; + } + case DatabaseMetaData.typePredNone: { + return NONE; + } + case DatabaseMetaData.typePredBasic: { + return BASIC; + } + case DatabaseMetaData.typePredChar: { + return CHAR; + } + default: { + throw new IllegalArgumentException( "Unknown type searchability code [" + code + "] enountered" ); + } + } + } +}