All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.itsallcode.jdbc.resultset.generic.GenericRowMapper Maven / Gradle / Ivy

There is a newer version: 0.7.1
Show newest version
package org.itsallcode.jdbc.resultset.generic;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;

import org.itsallcode.jdbc.UncheckedSQLException;
import org.itsallcode.jdbc.dialect.DbDialect;
import org.itsallcode.jdbc.resultset.*;

/**
 * This {@link ContextRowMapper} converts a row to the generic {@link Row} type.
 * 
 * @param  generic row type
 */
public class GenericRowMapper implements RowMapper {
    private ResultSetRowBuilder rowBuilder;
    private final ColumnValuesConverter converter;
    private final DbDialect dialect;

    /**
     * Create a new instance.
     * 
     * @param dialect   database dialect
     * @param converter optionally converts each generic {@link Row} to a different
     *                  type.
     */
    public GenericRowMapper(final DbDialect dialect, final ColumnValuesConverter converter) {
        this.dialect = Objects.requireNonNull(dialect, "dialect");
        this.converter = Objects.requireNonNull(converter, "converter");
    }

    @Override
    public T mapRow(final ResultSet resultSet, final int rowNum) throws SQLException {
        if (rowBuilder == null) {
            rowBuilder = new ResultSetRowBuilder(SimpleMetaData.create(resultSet));
        }
        final Row row = rowBuilder.buildRow(ConvertingResultSet.create(dialect, resultSet), rowNum);
        return converter.mapRow(row);
    }

    private class ResultSetRowBuilder {
        private final SimpleMetaData metadata;

        private ResultSetRowBuilder(final SimpleMetaData metaData) {
            this.metadata = metaData;
        }

        private Row buildRow(final ResultSet resultSet, final int rowIndex) {
            final List columns = metadata.columns();
            final List fields = new ArrayList<>(columns.size());
            for (final ColumnMetaData column : columns) {
                final ColumnValue field = getField(resultSet, column, rowIndex);
                fields.add(field);
            }
            return new Row(rowIndex, columns, fields);
        }

        private ColumnValue getField(final ResultSet resultSet, final ColumnMetaData column, final int rowIndex) {
            final Object value = getValue(resultSet, column, rowIndex);
            return new ColumnValue(column.type(), value);
        }

        private Object getValue(final ResultSet resultSet, final ColumnMetaData column, final int rowIndex) {
            try {
                return resultSet.getObject(column.columnIndex());
            } catch (final SQLException e) {
                throw new UncheckedSQLException("Error extracting value for row " + rowIndex + " / column " + column,
                        e);
            }
        }
    }

    /**
     * A simplified row mapper that gets a list of column values as input.
     * 
     * @param  generic row type
     */
    @FunctionalInterface
    public interface ColumnValuesConverter {
        /**
         * Convert a single row.
         * 
         * @param row column values
         * @return converted object
         */
        T mapRow(Row row);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy