package io.dropwizard.java8.jdbi.args;
import org.skife.jdbi.v2.util.TypedMapper;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.time.Instant;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Optional;
import java.util.TimeZone;
/**
* A {@link TypedMapper} to map {@link Instant} objects.
*/
public class InstantMapper extends TypedMapper<Instant> {
/**
* <p>{@link Calendar} for representing a database time zone.<p>
* If a field is not represented in a database as
* {@code TIMESTAMP WITH TIME ZONE}, we need to set its time zone
* explicitly. Otherwise it will not be correctly represented in
* a time zone different from the time zone of the database.
*/
private final Optional<Calendar> calendar;
public InstantMapper() {
this(Optional.empty());
}
public InstantMapper(final Optional<TimeZone> tz) {
this.calendar = tz.map(GregorianCalendar::new);
}
@Override
protected Instant extractByName(ResultSet r, String name) throws SQLException {
final Timestamp timestamp = calendar.isPresent() ? r.getTimestamp(name, cloneCalendar()) : r.getTimestamp(name);
return timestamp == null ? null : timestamp.toInstant();
}
@Override
protected Instant extractByIndex(ResultSet r, int index) throws SQLException {
final Timestamp timestamp = calendar.isPresent() ? r.getTimestamp(index, cloneCalendar()) : r.getTimestamp(index);
return timestamp == null ? null : timestamp.toInstant();
}
private Calendar cloneCalendar() {
return (Calendar) calendar.get().clone();
}
}