package org.oddjob.sql;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.sql.Date;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Time;
import java.sql.Timestamp;
import java.sql.Types;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* Something that is able to extract a value from a column based on the
* SQL Type.
*
* @author rob
*
*/
public abstract class ColumnExtractor<T> {
public static final Map<Integer, String> SQL_TYPE_NAMES =
new LinkedHashMap<Integer, String>();
static {
Field[] fields = Types.class.getFields();
for (Field field: fields) {
try {
SQL_TYPE_NAMES.put((Integer) field.get(null), field.getName());
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
public static final ColumnExtractor<Boolean> BOOLEAN_EXTRACTOR =
new ColumnExtractor<Boolean>() {
@Override
public java.lang.Class<Boolean> getType() {
return Boolean.class;
}
@Override
public Boolean extract(ResultSet rs, int columnIndex)
throws SQLException {
Boolean column = new Boolean(rs.getBoolean(columnIndex));
if (rs.wasNull()) {
return null;
}
else {
return column;
}
}
};
public static final ColumnExtractor<Short> SHORT_EXTRACTOR =
new ColumnExtractor<Short>() {
@Override
public java.lang.Class<Short> getType() {
return Short.class;
}
@Override
public Short extract(ResultSet rs, int columnIndex)
throws SQLException {
Short column = new Short(rs.getShort(columnIndex));
if (rs.wasNull()) {
return null;
}
else {
return column;
}
}
};
public static final ColumnExtractor<Integer> INT_EXTRACTOR =
new ColumnExtractor<Integer>() {
@Override
public java.lang.Class<Integer> getType() {
return Integer.class;
}
@Override
public Integer extract(ResultSet rs, int columnIndex)
throws SQLException {
Integer column = new Integer(rs.getInt(columnIndex));
if (rs.wasNull()) {
return null;
}
else {
return column;
}
}
};
public static final ColumnExtractor<Long> LONG_EXTRACTOR =
new ColumnExtractor<Long>() {
@Override
public java.lang.Class<Long> getType() {
return Long.class;
}
@Override
public Long extract(ResultSet rs, int columnIndex)
throws SQLException {
Long column = new Long(rs.getLong(columnIndex));
if (rs.wasNull()) {
return null;
}
else {
return column;
}
}
};
public static final ColumnExtractor<Double> DOUBLE_EXTRACTOR =
new ColumnExtractor<Double>() {
@Override
public java.lang.Class<Double> getType() {
return Double.class;
}
@Override
public Double extract(ResultSet rs, int columnIndex)
throws SQLException {
Double column = new Double(rs.getDouble(columnIndex));
if (rs.wasNull()) {
return null;
}
else {
return column;
}
}
};
public static final ColumnExtractor<BigDecimal> BIG_DECIMAL_EXTRACTOR =
new ColumnExtractor<BigDecimal>() {
@Override
public java.lang.Class<BigDecimal> getType() {
return BigDecimal.class;
}
@Override
public BigDecimal extract(ResultSet rs, int columnIndex)
throws SQLException {
BigDecimal column = rs.getBigDecimal(columnIndex);
if (rs.wasNull()) {
return null;
}
else {
return column;
}
}
};
public static final ColumnExtractor<String> STRING_EXTRACTOR =
new ColumnExtractor<String>() {
@Override
public java.lang.Class<String> getType() {
return String.class;
}
@Override
public String extract(ResultSet rs, int columnIndex)
throws SQLException {
return rs.getString(columnIndex);
}
};
public static final ColumnExtractor<Date> DATE_EXTRACTOR =
new ColumnExtractor<Date>() {
@Override
public java.lang.Class<Date> getType() {
return Date.class;
}
@Override
public Date extract(ResultSet rs, int columnIndex)
throws SQLException {
return rs.getDate(columnIndex);
}
};
public static final ColumnExtractor<Time> TIME_EXTRACTOR =
new ColumnExtractor<Time>() {
@Override
public java.lang.Class<Time> getType() {
return Time.class;
}
@Override
public Time extract(ResultSet rs, int columnIndex)
throws SQLException {
return rs.getTime(columnIndex);
}
};
public static final ColumnExtractor<Timestamp> TIMESTAMP_EXTRACTOR =
new ColumnExtractor<Timestamp>() {
@Override
public java.lang.Class<Timestamp> getType() {
return Timestamp.class;
}
@Override
public Timestamp extract(ResultSet rs, int columnIndex)
throws SQLException {
return rs.getTimestamp(columnIndex);
}
};
public static final ColumnExtractor<Object> DEFAULT_EXTRACTOR =
new ColumnExtractor<Object>() {
@Override
public java.lang.Class<Object> getType() {
return Object.class;
}
@Override
public Object extract(ResultSet rs, int columnIndex)
throws SQLException {
return rs.getObject(columnIndex);
}
};
private static final Map<Integer, ColumnExtractor<?>> EXTRACTOR_TYPES =
new HashMap<Integer, ColumnExtractor<?>>();
static {
EXTRACTOR_TYPES.put(Types.BIT, SHORT_EXTRACTOR);
EXTRACTOR_TYPES.put(Types.TINYINT, SHORT_EXTRACTOR);
EXTRACTOR_TYPES.put(Types.SMALLINT, SHORT_EXTRACTOR);
EXTRACTOR_TYPES.put(Types.INTEGER, INT_EXTRACTOR);
EXTRACTOR_TYPES.put(Types.BIGINT, LONG_EXTRACTOR);
EXTRACTOR_TYPES.put(Types.FLOAT, DOUBLE_EXTRACTOR);
EXTRACTOR_TYPES.put(Types.REAL, DOUBLE_EXTRACTOR);
EXTRACTOR_TYPES.put(Types.DOUBLE, DOUBLE_EXTRACTOR);
EXTRACTOR_TYPES.put(Types.NUMERIC, BIG_DECIMAL_EXTRACTOR);
EXTRACTOR_TYPES.put(Types.DECIMAL, BIG_DECIMAL_EXTRACTOR);
EXTRACTOR_TYPES.put(Types.CHAR, STRING_EXTRACTOR);
EXTRACTOR_TYPES.put(Types.VARCHAR, STRING_EXTRACTOR);
EXTRACTOR_TYPES.put(Types.LONGVARCHAR, STRING_EXTRACTOR);
EXTRACTOR_TYPES.put(Types.DATE, DATE_EXTRACTOR);
EXTRACTOR_TYPES.put(Types.TIME, TIME_EXTRACTOR);
EXTRACTOR_TYPES.put(Types.TIMESTAMP, TIMESTAMP_EXTRACTOR);
EXTRACTOR_TYPES.put(Types.BOOLEAN, BOOLEAN_EXTRACTOR);
EXTRACTOR_TYPES.put(Types.ROWID, LONG_EXTRACTOR);
EXTRACTOR_TYPES.put(Types.CLOB, STRING_EXTRACTOR);
}
@SuppressWarnings("unchecked")
public static <X> ColumnExtractor<X> getColumnExtractor(Integer sqlType) {
return (ColumnExtractor<X>) EXTRACTOR_TYPES.get(sqlType);
}
/**
* Get the class of this Column Extractor.
*
* @return The class, never null.
*/
abstract public Class<T> getType();
/**
* Extract the value from the column.
*
* @param rs
* @param columnIndex
* @return
* @throws SQLException
*/
abstract public T extract(ResultSet rs, int columnIndex) throws SQLException;
}