Search in sources :

Example 1 with RowMapper

use of org.jdbi.v3.core.mapper.RowMapper in project jdbi by jdbi.

the class BeanMapper method specialize0.

private RowMapper<T> specialize0(ResultSet rs, StatementContext ctx, List<String> columnNames, List<ColumnNameMatcher> columnNameMatchers, List<String> unmatchedColumns) throws SQLException {
    final List<RowMapper<?>> mappers = new ArrayList<>();
    final List<PropertyDescriptor> properties = new ArrayList<>();
    for (PropertyDescriptor descriptor : info.getPropertyDescriptors()) {
        Nested anno = Stream.of(descriptor.getReadMethod(), descriptor.getWriteMethod()).filter(Objects::nonNull).map(m -> m.getAnnotation(Nested.class)).filter(Objects::nonNull).findFirst().orElse(null);
        if (anno == null) {
            String paramName = prefix + paramName(descriptor);
            findColumnIndex(paramName, columnNames, columnNameMatchers, () -> debugName(descriptor)).ifPresent(index -> {
                Type type = descriptor.getReadMethod().getGenericReturnType();
                ColumnMapper<?> mapper = ctx.findColumnMapperFor(type).orElse((r, n, c) -> r.getObject(n));
                mappers.add(new SingleColumnMapper<>(mapper, index + 1));
                properties.add(descriptor);
                unmatchedColumns.remove(columnNames.get(index));
            });
        } else {
            String nestedPrefix = prefix + anno.value();
            RowMapper<?> nestedMapper = nestedMappers.computeIfAbsent(descriptor, d -> new BeanMapper<>(d.getPropertyType(), nestedPrefix)).specialize0(rs, ctx, columnNames, columnNameMatchers, unmatchedColumns);
            mappers.add(nestedMapper);
            properties.add(descriptor);
        }
    }
    if (mappers.isEmpty() && columnNames.size() > 0) {
        throw new IllegalArgumentException(String.format("Mapping bean type %s " + "didn't find any matching columns in result set", type));
    }
    return (r, c) -> {
        T bean = construct();
        for (int i = 0; i < mappers.size(); i++) {
            RowMapper<?> mapper = mappers.get(i);
            PropertyDescriptor property = properties.get(i);
            Object value = mapper.map(r, ctx);
            writeProperty(bean, property, value);
        }
        return bean;
    };
}
Also used : ReflectionMapperUtil.getColumnNames(org.jdbi.v3.core.mapper.reflect.ReflectionMapperUtil.getColumnNames) RowMapperFactory(org.jdbi.v3.core.mapper.RowMapperFactory) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Nested(org.jdbi.v3.core.mapper.Nested) SingleColumnMapper(org.jdbi.v3.core.mapper.SingleColumnMapper) IntrospectionException(java.beans.IntrospectionException) InvocationTargetException(java.lang.reflect.InvocationTargetException) ArrayList(java.util.ArrayList) StatementContext(org.jdbi.v3.core.statement.StatementContext) Objects(java.util.Objects) Introspector(java.beans.Introspector) SQLException(java.sql.SQLException) List(java.util.List) Stream(java.util.stream.Stream) Type(java.lang.reflect.Type) PropertyDescriptor(java.beans.PropertyDescriptor) ResultSet(java.sql.ResultSet) BeanInfo(java.beans.BeanInfo) Map(java.util.Map) ReflectionMapperUtil.findColumnIndex(org.jdbi.v3.core.mapper.reflect.ReflectionMapperUtil.findColumnIndex) ColumnMapper(org.jdbi.v3.core.mapper.ColumnMapper) RowMapper(org.jdbi.v3.core.mapper.RowMapper) PropertyDescriptor(java.beans.PropertyDescriptor) ArrayList(java.util.ArrayList) Nested(org.jdbi.v3.core.mapper.Nested) Type(java.lang.reflect.Type) Objects(java.util.Objects) RowMapper(org.jdbi.v3.core.mapper.RowMapper)

Example 2 with RowMapper

use of org.jdbi.v3.core.mapper.RowMapper in project jdbi by jdbi.

the class ResultBearing method collectInto.

/**
 * Collect the results into a container of the given type. A collector
 * must be registered for the container type, which knows the element type
 * for the container. A mapper must be registered for the element type.
 * <p>
 * This method is equivalent to {@code ResultBearing.mapTo(elementType).collect(containerCollector)}.
 * </p>
 *
 * @param containerType the container type into which results will be collected
 * @return a container into which result rows have been collected
 */
@SuppressWarnings({ "unchecked", "rawtypes" })
default Object collectInto(Type containerType) {
    return scanResultSet((rs, ctx) -> {
        Collector collector = ctx.findCollectorFor(containerType).orElseThrow(() -> new NoSuchCollectorException("No collector registered for container type " + containerType));
        Type elementType = ctx.findElementTypeFor(containerType).orElseThrow(() -> new ElementTypeNotFoundException("Unknown element type for container type " + containerType));
        RowMapper<?> mapper = ctx.findMapperFor(elementType).orElseThrow(() -> new NoSuchMapperException("No mapper registered for element type " + elementType));
        return ResultIterable.of(rs, mapper, ctx).collect(collector);
    });
}
Also used : GenericType(org.jdbi.v3.core.generic.GenericType) Type(java.lang.reflect.Type) ElementTypeNotFoundException(org.jdbi.v3.core.collector.ElementTypeNotFoundException) Collector(java.util.stream.Collector) NoSuchCollectorException(org.jdbi.v3.core.collector.NoSuchCollectorException) NoSuchMapperException(org.jdbi.v3.core.mapper.NoSuchMapperException)

Example 3 with RowMapper

use of org.jdbi.v3.core.mapper.RowMapper in project jdbi by jdbi.

the class MapMapper method specialize.

@Override
public RowMapper<Map<String, Object>> specialize(ResultSet rs, StatementContext ctx) throws SQLException {
    ResultSetMetaData m = rs.getMetaData();
    int columnCount = m.getColumnCount();
    String[] columnNames = new String[columnCount + 1];
    for (int i = 1; i <= columnCount; i++) {
        String key = m.getColumnName(i);
        String alias = m.getColumnLabel(i);
        if (alias == null) {
            alias = key;
        }
        if (foldCase) {
            alias = alias.toLowerCase(Locale.ROOT);
        }
        columnNames[i] = alias;
    }
    return (r, c) -> {
        Map<String, Object> row = new LinkedHashMap<>(columnCount);
        for (int i = 1; i <= columnCount; i++) {
            row.put(columnNames[i], rs.getObject(i));
        }
        return row;
    };
}
Also used : ResultSetMetaData(java.sql.ResultSetMetaData) LinkedHashMap(java.util.LinkedHashMap) SQLException(java.sql.SQLException) ResultSet(java.sql.ResultSet) Locale(java.util.Locale) Map(java.util.Map) ResultSetMetaData(java.sql.ResultSetMetaData) StatementContext(org.jdbi.v3.core.statement.StatementContext) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map)

Example 4 with RowMapper

use of org.jdbi.v3.core.mapper.RowMapper in project jdbi by jdbi.

the class JpaMapper method specialize.

@Override
public RowMapper<C> specialize(ResultSet rs, StatementContext ctx) throws SQLException {
    Constructor<C> constructor;
    try {
        constructor = clazz.getDeclaredConstructor();
    } catch (ReflectiveOperationException e) {
        throw new EntityMemberAccessException("Unable to get constructor for " + clazz, e);
    }
    constructor.setAccessible(true);
    List<MemberSetter<C>> setters = new ArrayList<>();
    for (int colIndex = rs.getMetaData().getColumnCount(); colIndex >= 1; colIndex--) {
        String columnLabel = rs.getMetaData().getColumnLabel(colIndex);
        JpaMember member = jpaClass.lookupMember(columnLabel);
        if (member != null) {
            Type memberType = member.getType();
            ColumnMapper<?> columnMapper = ctx.findColumnMapperFor(memberType).orElseThrow(() -> new NoSuchMapperException("No column mapper for " + memberType));
            final int columnIndex = colIndex;
            setters.add(obj -> member.write(obj, columnMapper.map(rs, columnIndex, ctx)));
        }
    }
    return (r, c) -> {
        C obj;
        try {
            obj = constructor.newInstance();
        } catch (ReflectiveOperationException e) {
            throw new EntityMemberAccessException("Unable to invoke " + constructor, e);
        }
        for (MemberSetter<C> setter : setters) {
            setter.mapAndSetMember(obj);
        }
        return obj;
    };
}
Also used : SQLException(java.sql.SQLException) List(java.util.List) Type(java.lang.reflect.Type) ResultSet(java.sql.ResultSet) ColumnMapper(org.jdbi.v3.core.mapper.ColumnMapper) JpaMember(org.jdbi.v3.jpa.internal.JpaMember) NoSuchMapperException(org.jdbi.v3.core.mapper.NoSuchMapperException) Constructor(java.lang.reflect.Constructor) ArrayList(java.util.ArrayList) RowMapper(org.jdbi.v3.core.mapper.RowMapper) StatementContext(org.jdbi.v3.core.statement.StatementContext) JpaClass(org.jdbi.v3.jpa.internal.JpaClass) ArrayList(java.util.ArrayList) NoSuchMapperException(org.jdbi.v3.core.mapper.NoSuchMapperException) Type(java.lang.reflect.Type) JpaMember(org.jdbi.v3.jpa.internal.JpaMember)

Example 5 with RowMapper

use of org.jdbi.v3.core.mapper.RowMapper in project presto by prestodb.

the class H2QueryRunner method rowMapper.

private static RowMapper<MaterializedRow> rowMapper(List<? extends Type> types) {
    return new RowMapper<MaterializedRow>() {

        private Object getValue(Type type, ResultSet resultSet, int position) throws SQLException {
            if (BOOLEAN.equals(type)) {
                boolean booleanValue = resultSet.getBoolean(position);
                return resultSet.wasNull() ? null : booleanValue;
            } else if (TINYINT.equals(type)) {
                byte byteValue = resultSet.getByte(position);
                return resultSet.wasNull() ? null : byteValue;
            } else if (SMALLINT.equals(type)) {
                short shortValue = resultSet.getShort(position);
                return resultSet.wasNull() ? null : shortValue;
            } else if (INTEGER.equals(type)) {
                int intValue = resultSet.getInt(position);
                return resultSet.wasNull() ? null : intValue;
            } else if (BIGINT.equals(type)) {
                long longValue = resultSet.getLong(position);
                return resultSet.wasNull() ? null : longValue;
            } else if (REAL.equals(type)) {
                float floatValue = resultSet.getFloat(position);
                return resultSet.wasNull() ? null : floatValue;
            } else if (DOUBLE.equals(type)) {
                double doubleValue = resultSet.getDouble(position);
                return resultSet.wasNull() ? null : doubleValue;
            } else if (isVarcharType(type)) {
                String stringValue = resultSet.getString(position);
                return resultSet.wasNull() ? null : stringValue;
            } else if (isCharType(type)) {
                String stringValue = resultSet.getString(position);
                return resultSet.wasNull() ? null : padEnd(stringValue, ((CharType) type).getLength(), ' ');
            } else if (VARBINARY.equals(type)) {
                byte[] binary = resultSet.getBytes(position);
                return resultSet.wasNull() ? null : binary;
            } else if (DATE.equals(type)) {
                // resultSet.getDate(i) doesn't work if JVM's zone skipped day being retrieved (e.g. 2011-12-30 and Pacific/Apia zone)
                LocalDate dateValue = resultSet.getObject(position, LocalDate.class);
                return resultSet.wasNull() ? null : dateValue;
            } else if (TIME.equals(type)) {
                // resultSet.getTime(i) doesn't work if JVM's zone had forward offset change during 1970-01-01 (e.g. America/Hermosillo zone)
                LocalTime timeValue = resultSet.getObject(position, LocalTime.class);
                return resultSet.wasNull() ? null : timeValue;
            } else if (TIME_WITH_TIME_ZONE.equals(type)) {
                throw new UnsupportedOperationException("H2 does not support TIME WITH TIME ZONE");
            } else if (TIMESTAMP.equals(type)) {
                // resultSet.getTimestamp(i) doesn't work if JVM's zone had forward offset at the date/time being retrieved
                LocalDateTime timestampValue;
                try {
                    timestampValue = resultSet.getObject(position, LocalDateTime.class);
                } catch (SQLException first) {
                    // H2 cannot convert DATE to LocalDateTime in their JDBC driver (even though it can convert to java.sql.Timestamp), we need to do this manually
                    try {
                        timestampValue = Optional.ofNullable(resultSet.getObject(position, LocalDate.class)).map(LocalDate::atStartOfDay).orElse(null);
                    } catch (RuntimeException e) {
                        first.addSuppressed(e);
                        throw first;
                    }
                }
                return resultSet.wasNull() ? null : timestampValue;
            } else if (TIMESTAMP_WITH_TIME_ZONE.equals(type)) {
                // This means H2 is unsuitable for testing TIMESTAMP WITH TIME ZONE-bearing queries. Those need to be tested manually.
                throw new UnsupportedOperationException();
            } else if (UNKNOWN.equals(type)) {
                Object objectValue = resultSet.getObject(position);
                checkState(resultSet.wasNull(), "Expected a null value, but got %s", objectValue);
                return null;
            } else if (type instanceof DecimalType) {
                DecimalType decimalType = (DecimalType) type;
                BigDecimal decimalValue = resultSet.getBigDecimal(position);
                return resultSet.wasNull() ? null : decimalValue.setScale(decimalType.getScale(), BigDecimal.ROUND_HALF_UP).round(new MathContext(decimalType.getPrecision()));
            } else if (type instanceof ArrayType) {
                Array array = resultSet.getArray(position);
                return resultSet.wasNull() ? null : newArrayList(mapArrayValues(((ArrayType) type), (Object[]) array.getArray()));
            } else if (type instanceof RowType) {
                Array array = resultSet.getArray(position);
                return resultSet.wasNull() ? null : newArrayList(mapRowValues((RowType) type, (Object[]) array.getArray()));
            } else if (type instanceof TypeWithName) {
                return getValue(((TypeWithName) type).getType(), resultSet, position);
            } else {
                throw new AssertionError("unhandled type: " + type);
            }
        }

        @Override
        public MaterializedRow map(ResultSet resultSet, StatementContext context) throws SQLException {
            int count = resultSet.getMetaData().getColumnCount();
            checkArgument(types.size() == count, "expected types count (%s) does not match actual column count (%s)", types.size(), count);
            List<Object> row = new ArrayList<>(count);
            for (int i = 1; i <= count; i++) {
                row.add(getValue(types.get(i - 1), resultSet, i));
            }
            return new MaterializedRow(MaterializedResult.DEFAULT_PRECISION, row);
        }
    };
}
Also used : LocalDateTime(java.time.LocalDateTime) SQLException(java.sql.SQLException) Lists.newArrayList(com.google.common.collect.Lists.newArrayList) ArrayList(java.util.ArrayList) RowType(com.facebook.presto.common.type.RowType) LocalDate(java.time.LocalDate) StatementContext(org.jdbi.v3.core.statement.StatementContext) ArrayType(com.facebook.presto.common.type.ArrayType) ResultSet(java.sql.ResultSet) RowMapper(org.jdbi.v3.core.mapper.RowMapper) TypeWithName(com.facebook.presto.common.type.TypeWithName) LocalTime(java.time.LocalTime) BigDecimal(java.math.BigDecimal) MathContext(java.math.MathContext) Array(java.sql.Array) Varchars.isVarcharType(com.facebook.presto.common.type.Varchars.isVarcharType) VarcharType(com.facebook.presto.common.type.VarcharType) TimestampType(com.facebook.presto.common.type.TimestampType) DecimalType(com.facebook.presto.common.type.DecimalType) Chars.isCharType(com.facebook.presto.common.type.Chars.isCharType) ArrayType(com.facebook.presto.common.type.ArrayType) CharType(com.facebook.presto.common.type.CharType) Type(com.facebook.presto.common.type.Type) RowType(com.facebook.presto.common.type.RowType) DecimalType(com.facebook.presto.common.type.DecimalType) Chars.isCharType(com.facebook.presto.common.type.Chars.isCharType) CharType(com.facebook.presto.common.type.CharType) MaterializedRow(com.facebook.presto.testing.MaterializedRow)

Aggregations

ResultSet (java.sql.ResultSet)7 SQLException (java.sql.SQLException)7 StatementContext (org.jdbi.v3.core.statement.StatementContext)7 Type (java.lang.reflect.Type)6 ArrayList (java.util.ArrayList)5 Map (java.util.Map)5 RowMapper (org.jdbi.v3.core.mapper.RowMapper)5 List (java.util.List)4 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)3 ColumnMapper (org.jdbi.v3.core.mapper.ColumnMapper)3 Constructor (java.lang.reflect.Constructor)2 InvocationTargetException (java.lang.reflect.InvocationTargetException)2 Nested (org.jdbi.v3.core.mapper.Nested)2 NoSuchMapperException (org.jdbi.v3.core.mapper.NoSuchMapperException)2 RowMapperFactory (org.jdbi.v3.core.mapper.RowMapperFactory)2 SingleColumnMapper (org.jdbi.v3.core.mapper.SingleColumnMapper)2 ReflectionMapperUtil.findColumnIndex (org.jdbi.v3.core.mapper.reflect.ReflectionMapperUtil.findColumnIndex)2 ReflectionMapperUtil.getColumnNames (org.jdbi.v3.core.mapper.reflect.ReflectionMapperUtil.getColumnNames)2 ArrayType (com.facebook.presto.common.type.ArrayType)1 CharType (com.facebook.presto.common.type.CharType)1