JdbcFieldInfo.java
/*
* 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.arrow.adapter.jdbc;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Types;
import org.apache.arrow.util.Preconditions;
/**
* This class represents the information about a JDBC ResultSet Field that is needed to construct an
* {@link org.apache.arrow.vector.types.pojo.ArrowType}. Currently, this is:
*
* <ul>
* <li>The JDBC {@link java.sql.Types} type.
* <li>The nullability.
* <li>The field's precision (used for {@link java.sql.Types#DECIMAL} and {@link
* java.sql.Types#NUMERIC} types).
* <li>The field's scale (used for {@link java.sql.Types#DECIMAL} and {@link
* java.sql.Types#NUMERIC} types).
* </ul>
*/
public class JdbcFieldInfo {
private final int column;
private final int jdbcType;
private final int nullability;
private final int precision;
private final int scale;
private final String typeName;
private final int displaySize;
/**
* Builds a <code>JdbcFieldInfo</code> using only the {@link java.sql.Types} type. Do not use this
* constructor if the field type is {@link java.sql.Types#DECIMAL} or {@link
* java.sql.Types#NUMERIC}; the precision and scale will be set to <code>0</code>.
*
* @param jdbcType The {@link java.sql.Types} type.
* @throws IllegalArgumentException if jdbcType is {@link java.sql.Types#DECIMAL} or {@link
* java.sql.Types#NUMERIC}.
*/
public JdbcFieldInfo(int jdbcType) {
Preconditions.checkArgument(
(jdbcType != Types.DECIMAL && jdbcType != Types.NUMERIC),
"DECIMAL and NUMERIC types require a precision and scale; please use another constructor.");
this.column = 0;
this.jdbcType = jdbcType;
this.nullability = ResultSetMetaData.columnNullableUnknown;
this.precision = 0;
this.scale = 0;
this.typeName = "";
this.displaySize = 0;
}
/**
* Builds a <code>JdbcFieldInfo</code> from the {@link java.sql.Types} type, precision, and scale.
* Use this constructor for {@link java.sql.Types#DECIMAL} and {@link java.sql.Types#NUMERIC}
* types.
*
* @param jdbcType The {@link java.sql.Types} type.
* @param precision The field's numeric precision.
* @param scale The field's numeric scale.
*/
public JdbcFieldInfo(int jdbcType, int precision, int scale) {
this.column = 0;
this.jdbcType = jdbcType;
this.nullability = ResultSetMetaData.columnNullableUnknown;
this.precision = precision;
this.scale = scale;
this.typeName = "";
this.displaySize = 0;
}
/**
* Builds a <code>JdbcFieldInfo</code> from the {@link java.sql.Types} type, nullability,
* precision, and scale.
*
* @param jdbcType The {@link java.sql.Types} type.
* @param nullability The nullability. Must be one of {@link ResultSetMetaData#columnNoNulls},
* {@link ResultSetMetaData#columnNullable}, or {@link
* ResultSetMetaData#columnNullableUnknown}.
* @param precision The field's numeric precision.
* @param scale The field's numeric scale.
*/
public JdbcFieldInfo(int jdbcType, int nullability, int precision, int scale) {
this.column = 0;
this.jdbcType = jdbcType;
this.nullability = nullability;
this.precision = precision;
this.scale = scale;
this.typeName = "";
this.displaySize = 0;
}
/**
* Builds a <code>JdbcFieldInfo</code> from the corresponding {@link java.sql.ResultSetMetaData}
* column.
*
* @param rsmd The {@link java.sql.ResultSetMetaData} to get the field information from.
* @param column The column to get the field information for (on a 1-based index).
* @throws SQLException If the column information cannot be retrieved.
* @throws NullPointerException if <code>rsmd</code> is <code>null</code>.
* @throws IllegalArgumentException if <code>column</code> is out of bounds.
*/
public JdbcFieldInfo(ResultSetMetaData rsmd, int column) throws SQLException {
Preconditions.checkNotNull(rsmd, "ResultSetMetaData cannot be null.");
Preconditions.checkArgument(
column > 0, "ResultSetMetaData columns have indices starting at 1.");
Preconditions.checkArgument(
column <= rsmd.getColumnCount(),
"The index must be within the number of columns (1 to %s, inclusive)",
rsmd.getColumnCount());
this.column = column;
this.jdbcType = rsmd.getColumnType(column);
this.nullability = rsmd.isNullable(column);
this.precision = rsmd.getPrecision(column);
this.scale = rsmd.getScale(column);
this.typeName = rsmd.getColumnTypeName(column);
this.displaySize = rsmd.getColumnDisplaySize(column);
}
/**
* Builds a <code>JdbcFieldInfo</code> from the corresponding row from a {@link
* java.sql.DatabaseMetaData#getColumns} ResultSet.
*
* @param rs The {@link java.sql.ResultSet} to get the field information from.
* @throws SQLException If the column information cannot be retrieved.
*/
public JdbcFieldInfo(ResultSet rs) throws SQLException {
this.column = rs.getInt("ORDINAL_POSITION");
this.jdbcType = rs.getInt("DATA_TYPE");
this.nullability = rs.getInt("NULLABLE");
this.precision = rs.getInt("COLUMN_SIZE");
this.scale = rs.getInt("DECIMAL_DIGITS");
this.typeName = rs.getString("TYPE_NAME");
this.displaySize = rs.getInt("CHAR_OCTET_LENGTH");
}
/** The {@link java.sql.Types} type. */
public int getJdbcType() {
return jdbcType;
}
/** The nullability. */
public int isNullable() {
return nullability;
}
/**
* The numeric precision, for {@link java.sql.Types#NUMERIC} and {@link java.sql.Types#DECIMAL}
* types.
*/
public int getPrecision() {
return precision;
}
/**
* The numeric scale, for {@link java.sql.Types#NUMERIC} and {@link java.sql.Types#DECIMAL} types.
*/
public int getScale() {
return scale;
}
/** The column index for query column. */
public int getColumn() {
return column;
}
/** The type name as reported by the database. */
public String getTypeName() {
return typeName;
}
/** The max number of characters for the column. */
public int getDisplaySize() {
return displaySize;
}
}