001package org.itsallcode.jdbc.resultset;
002
003import java.sql.ResultSet;
004import java.sql.SQLException;
005import java.util.List;
006
007import org.itsallcode.jdbc.dialect.DbDialect;
008import org.itsallcode.jdbc.resultset.generic.SimpleMetaData;
009
010/**
011 * A {@link ResultSet} that automatically converts values to modern types in the
012 * following methods:
013 * <ul>
014 * <li>{@link ResultSet#getObject(String)}</li>
015 * <li>{@link ResultSet#getObject(String, Class)}</li>
016 * <li>{@link ResultSet#getObject(int)}</li>
017 * <li>{@link ResultSet#getObject(int, Class)}</li>
018 * </ul>
019 */
020public final class ConvertingResultSet extends DelegatingResultSet {
021    private final ResultSet delegate;
022    private final ResultSetValueConverter converter;
023
024    private ConvertingResultSet(final ResultSet delegate, final ResultSetValueConverter converter) {
025        super(delegate);
026        this.delegate = delegate;
027        this.converter = converter;
028    }
029
030    /**
031     * Create a new converting result set.
032     * 
033     * @param dialect  DB dialect
034     * @param delegate the original result set.
035     * @return a new converting result set.
036     */
037    public static ConvertingResultSet create(final DbDialect dialect, final ResultSet delegate) {
038        final SimpleMetaData metaData = SimpleMetaData.create(delegate);
039        final List<ColumnValueConverter> converters = metaData.columns().stream()
040                .map(col -> ColumnValueConverter.simple(dialect.createExtractor(col)))
041                .toList();
042        return new ConvertingResultSet(delegate, ResultSetValueConverter.create(metaData, converters));
043    }
044
045    @Override
046    public <T> T getObject(final int columnIndex, final Class<T> type) throws SQLException {
047        return converter.getObject(delegate, columnIndex, type);
048    }
049
050    @Override
051    public <T> T getObject(final String columnLabel, final Class<T> type) throws SQLException {
052        return converter.getObject(delegate, columnLabel, type);
053    }
054
055    @Override
056    public Object getObject(final int columnIndex) throws SQLException {
057        return converter.getObject(delegate, columnIndex);
058    }
059
060    @Override
061    public Object getObject(final String columnLabel) throws SQLException {
062        return converter.getObject(delegate, columnLabel);
063    }
064}