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;
};
}
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);
});
}
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;
};
}
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;
};
}
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);
}
};
}
Aggregations