001package org.itsallcode.jdbc.resultset; 002 003import java.sql.ResultSet; 004import java.sql.SQLException; 005import java.util.List; 006 007import org.itsallcode.jdbc.Context; 008import org.itsallcode.jdbc.dialect.DbDialect; 009import org.itsallcode.jdbc.resultset.generic.*; 010import org.itsallcode.jdbc.resultset.generic.GenericRowMapper.ColumnValuesConverter; 011 012/** 013 * Converts a single row from a {@link ResultSet} to a generic row type. 014 * 015 * @param <T> generic row type 016 */ 017@FunctionalInterface 018public interface ContextRowMapper<T> { 019 020 /** 021 * Converts a single row from a {@link ResultSet} to a generic row type. 022 * 023 * @param context database context 024 * @param resultSet result set 025 * @param rowNum the current row number (zero based) 026 * @return the converted row 027 * @throws SQLException if accessing the result set fails 028 */ 029 T mapRow(Context context, ResultSet resultSet, int rowNum) throws SQLException; 030 031 /** 032 * Create a {@link RowMapper} that creates generic {@link Row} objects. 033 * 034 * @param dialect DB dialect 035 * @return a new row mapper 036 */ 037 static RowMapper<Row> generic(final DbDialect dialect) { 038 return generic(dialect, row -> row); 039 } 040 041 /** 042 * Create a {@link RowMapper} that creates {@link List}s of simple column 043 * objects. 044 * 045 * @param dialect DB dialect 046 * @return a new row mapper 047 */ 048 static RowMapper<List<Object>> columnValueList(final DbDialect dialect) { 049 return generic(dialect, row -> row.columnValues().stream().map(ColumnValue::value).toList()); 050 } 051 052 private static <T> RowMapper<T> generic(final DbDialect dialect, final ColumnValuesConverter<T> converter) { 053 return new GenericRowMapper<>(dialect, converter); 054 } 055 056 /** 057 * Creates a new new {@link ContextRowMapper} from a {@link SimpleRowMapper}. 058 * <p> 059 * Use this if the mapper doesn't need the {@link Context}. 060 * 061 * @param <T> generic row type 062 * @param mapper the simple row mapper 063 * @return a new {@link ContextRowMapper} 064 */ 065 static <T> ContextRowMapper<T> create(final SimpleRowMapper<T> mapper) { 066 return (context, resultSet, rowNum) -> mapper.mapRow(resultSet); 067 } 068 069 /** 070 * Creates a new new {@link ContextRowMapper} from a {@link RowMapper}. 071 * <p> 072 * Use this if the mapper doesn't need the {@link Context}. 073 * 074 * @param <T> generic row type 075 * @param mapper the simple row mapper 076 * @return a new {@link ContextRowMapper} 077 */ 078 static <T> ContextRowMapper<T> create(final RowMapper<T> mapper) { 079 return (context, resultSet, rowNum) -> mapper.mapRow(resultSet, rowNum); 080 } 081}