package org.jdbi.v3.core.mapper;
import java.lang.reflect.Type;
import java.sql.ResultSet;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.Optional;
import java.util.OptionalDouble;
import java.util.OptionalInt;
import java.util.OptionalLong;
import java.util.function.Function;
import java.util.function.Supplier;
import org.jdbi.v3.core.config.ConfigRegistry;
import static org.jdbi.v3.core.generic.GenericTypes.getErasedType;
class OptionalMapperFactory implements ColumnMapperFactory {
private final Map<Class<?>, ColumnMapper<?>> mappers = new IdentityHashMap<>();
OptionalMapperFactory() {
mappers.put(OptionalInt.class, optionalMapper(ResultSet::getInt, OptionalInt::empty, OptionalInt::of));
mappers.put(OptionalLong.class, optionalMapper(ResultSet::getLong, OptionalLong::empty, OptionalLong::of));
mappers.put(OptionalDouble.class, optionalMapper(ResultSet::getDouble, OptionalDouble::empty, OptionalDouble::of));
}
@Override
public Optional<ColumnMapper<?>> build(Type type, ConfigRegistry config) {
Class<?> rawType = getErasedType(type);
if (rawType == Optional.class) {
return Optional.of(OptionalMapper.of(type));
}
return Optional.ofNullable(mappers.get(rawType));
}
private static <Opt, Box> ColumnMapper<?> optionalMapper(ColumnGetter<Box> columnGetter, Supplier<Opt> empty, Function<Box, Opt> present) {
return (r, columnNumber, ctx) -> Optional.ofNullable(new GetterMapper<>(columnGetter).map(r, columnNumber, ctx))
.map(present)
.orElseGet(empty);
}
}