From fe2a6eec22084ef0601cbb0fa71ae1f048a495a0 Mon Sep 17 00:00:00 2001 From: moparisthebest Date: Tue, 13 Jun 2017 22:56:00 -0400 Subject: [PATCH] Support for java.time api classes --- .../jdbc/util/ResultSetUtil.java | 97 +++++++++++++++++- .../jdbc/codegen/JdbcMapperTest.java | 92 ++++++++++++++++- .../jdbc/codegen/PersonDAO.java | 41 ++++++++ .../jdbc/codegen/PrestoPersonDAO.java | 41 ++++++++ .../jdbc/CompilingRowToObjectMapper.java | 54 ++++++++++ .../jdbc/RowToObjectMapper.java | 30 ++++++ .../jdbc/TypeMappingsFactory.java | 50 +++++++--- .../moparisthebest/jdbc/QueryMapperTest.java | 99 ++++++++++++++++++- .../java/com/moparisthebest/jdbc/dto/Val.java | 15 +++ 9 files changed, 500 insertions(+), 19 deletions(-) create mode 100644 querymapper/src/test/java/com/moparisthebest/jdbc/dto/Val.java diff --git a/common/src/main/java/com/moparisthebest/jdbc/util/ResultSetUtil.java b/common/src/main/java/com/moparisthebest/jdbc/util/ResultSetUtil.java index 29e7d1f..bbc783c 100644 --- a/common/src/main/java/com/moparisthebest/jdbc/util/ResultSetUtil.java +++ b/common/src/main/java/com/moparisthebest/jdbc/util/ResultSetUtil.java @@ -2,9 +2,10 @@ package com.moparisthebest.jdbc.util; import java.sql.ResultSet; import java.sql.SQLException; -import java.sql.Time; -import java.sql.Timestamp; import java.util.Calendar; +//IFJAVA8_START +import java.time.*; +//IFJAVA8_END /** * Created by mopar on 5/16/17. @@ -79,6 +80,8 @@ public class ResultSetUtil { } public static java.util.Date getUtilDate(final ResultSet _resultSet, final int index, final Calendar _cal) throws SQLException { + if(_cal == null) + return getUtilDate(_resultSet, index); // convert explicity to java.util.Date // 12918 | knex does not return java.sql.Date properly from web service java.sql.Timestamp ts = _resultSet.getTimestamp(index, _cal); @@ -97,6 +100,8 @@ public class ResultSetUtil { } public static Calendar getCalendar(final ResultSet _resultSet, final int index, final Calendar _cal) throws SQLException { + if(_cal == null) + return getCalendar(_resultSet, index); java.sql.Timestamp ts = _resultSet.getTimestamp(index, _cal); if (null == ts) return null; @@ -105,4 +110,92 @@ public class ResultSetUtil { return c; } + //IFJAVA8_START + + public static Instant getInstant(final ResultSet _resultSet, final int index) throws SQLException { + final java.sql.Timestamp ts = _resultSet.getTimestamp(index); + return ts == null ? null : ts.toInstant(); + } + + public static Instant getInstant(final ResultSet _resultSet, final int index, final Calendar _cal) throws SQLException { + if(_cal == null) + return getInstant(_resultSet, index); + final java.sql.Timestamp ts = _resultSet.getTimestamp(index, _cal); + return ts == null ? null : ts.toInstant(); + } + + public static LocalDateTime getLocalDateTime(final ResultSet _resultSet, final int index) throws SQLException { + final java.sql.Timestamp ts = _resultSet.getTimestamp(index); + return ts == null ? null : ts.toLocalDateTime(); + } + + public static LocalDateTime getLocalDateTime(final ResultSet _resultSet, final int index, final Calendar _cal) throws SQLException { + if(_cal == null) + return getLocalDateTime(_resultSet, index); + final java.sql.Timestamp ts = _resultSet.getTimestamp(index, _cal); + return ts == null ? null : ts.toLocalDateTime(); + } + + public static LocalDate getLocalDate(final ResultSet _resultSet, final int index) throws SQLException { + final java.sql.Date ts = _resultSet.getDate(index); + return ts == null ? null : ts.toLocalDate(); + } + + public static LocalDate getLocalDate(final ResultSet _resultSet, final int index, final Calendar _cal) throws SQLException { + if(_cal == null) + return getLocalDate(_resultSet, index); + final java.sql.Date ts = _resultSet.getDate(index, _cal); + return ts == null ? null : ts.toLocalDate(); + } + + public static LocalTime getLocalTime(final ResultSet _resultSet, final int index) throws SQLException { + final java.sql.Time ts = _resultSet.getTime(index); + return ts == null ? null : ts.toLocalTime(); + } + + public static LocalTime getLocalTime(final ResultSet _resultSet, final int index, final Calendar _cal) throws SQLException { + if(_cal == null) + return getLocalTime(_resultSet, index); + final java.sql.Time ts = _resultSet.getTime(index, _cal); + return ts == null ? null : ts.toLocalTime(); + } + + public static ZonedDateTime getZonedDateTime(final ResultSet _resultSet, final int index) throws SQLException { + final java.sql.Timestamp ts = _resultSet.getTimestamp(index); + return ts == null ? null : ZonedDateTime.ofInstant(ts.toInstant(), ZoneId.systemDefault()); + } + + public static ZonedDateTime getZonedDateTime(final ResultSet _resultSet, final int index, final Calendar _cal) throws SQLException { + if(_cal == null) + return getZonedDateTime(_resultSet, index); + final java.sql.Timestamp ts = _resultSet.getTimestamp(index, _cal); + return ts == null ? null : ZonedDateTime.ofInstant(ts.toInstant(), _cal.getTimeZone().toZoneId()); + } + + public static OffsetDateTime getOffsetDateTime(final ResultSet _resultSet, final int index) throws SQLException { + final java.sql.Timestamp ts = _resultSet.getTimestamp(index); + return ts == null ? null : OffsetDateTime.ofInstant(ts.toInstant(), ZoneId.systemDefault()); + } + + public static OffsetDateTime getOffsetDateTime(final ResultSet _resultSet, final int index, final Calendar _cal) throws SQLException { + if(_cal == null) + return getOffsetDateTime(_resultSet, index); + final java.sql.Timestamp ts = _resultSet.getTimestamp(index, _cal); + return ts == null ? null : OffsetDateTime.ofInstant(ts.toInstant(), _cal.getTimeZone().toZoneId()); + } + + public static OffsetTime getOffsetTime(final ResultSet _resultSet, final int index) throws SQLException { + final java.sql.Timestamp ts = _resultSet.getTimestamp(index); + return ts == null ? null : OffsetTime.ofInstant(ts.toInstant(), ZoneId.systemDefault()); + } + + public static OffsetTime getOffsetTime(final ResultSet _resultSet, final int index, final Calendar _cal) throws SQLException { + if(_cal == null) + return getOffsetTime(_resultSet, index); + final java.sql.Timestamp ts = _resultSet.getTimestamp(index, _cal); + return ts == null ? null : OffsetTime.ofInstant(ts.toInstant(), _cal.getTimeZone().toZoneId()); + } + + //IFJAVA8_END + } diff --git a/jdbcmapper/src/test/java/com/moparisthebest/jdbc/codegen/JdbcMapperTest.java b/jdbcmapper/src/test/java/com/moparisthebest/jdbc/codegen/JdbcMapperTest.java index 3505f91..bbde352 100644 --- a/jdbcmapper/src/test/java/com/moparisthebest/jdbc/codegen/JdbcMapperTest.java +++ b/jdbcmapper/src/test/java/com/moparisthebest/jdbc/codegen/JdbcMapperTest.java @@ -3,6 +3,7 @@ package com.moparisthebest.jdbc.codegen; import com.moparisthebest.jdbc.dto.EnumPerson; import com.moparisthebest.jdbc.dto.FieldPerson; import com.moparisthebest.jdbc.dto.FirstName; +import com.moparisthebest.jdbc.dto.Val; import com.moparisthebest.jdbc.util.ResultSetIterable; import org.junit.AfterClass; import org.junit.BeforeClass; @@ -14,11 +15,10 @@ import java.util.List; //IFJAVA8_START import java.util.stream.Collectors; import java.util.stream.Stream; +import java.time.*; //IFJAVA8_END -import static com.moparisthebest.jdbc.QueryMapperTest.fieldPerson1; -import static com.moparisthebest.jdbc.QueryMapperTest.getConnection; -import static com.moparisthebest.jdbc.QueryMapperTest.people; +import static com.moparisthebest.jdbc.QueryMapperTest.*; import static com.moparisthebest.jdbc.TryClose.tryClose; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; @@ -103,4 +103,90 @@ public class JdbcMapperTest { public void testEnum() throws SQLException { assertEquals(FirstName.First, dao.getFirstNameEnum(fieldPerson1.getPersonNo())); } + + //IFJAVA8_START + + @Test + public void testInstant() throws SQLException { + assertEquals(fieldPerson1.getBirthDate().toInstant(), + dao.getBirthDateInstant(fieldPerson1.getPersonNo())); + } + + @Test + public void testLocalDateTime() throws SQLException { + assertEquals(fieldPerson1.getBirthDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(), + dao.getBirthDateLocalDateTime(fieldPerson1.getPersonNo())); + } + + @Test + public void testLocalDate() throws SQLException { + assertEquals(fieldPerson1.getBirthDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate(), + dao.getBirthDateLocalDate(fieldPerson1.getPersonNo())); + } + + @Test + public void testLocalTime() throws SQLException { + assertEquals(fieldPerson1.getBirthDate().toInstant().atZone(ZoneId.systemDefault()).toLocalTime(), + dao.getBirthDateLocalTime(fieldPerson1.getPersonNo())); + } + + @Test + public void testZonedDateTime() throws SQLException { + assertEquals(fieldPerson1.getBirthDate().toInstant().atZone(ZoneId.systemDefault()), + dao.getBirthDateZonedDateTime(fieldPerson1.getPersonNo())); + } + + @Test + public void testOffsetDateTime() throws SQLException { + assertEquals(fieldPerson1.getBirthDate().toInstant().atZone(ZoneId.systemDefault()).toOffsetDateTime(), + dao.getBirthDateOffsetDateTime(fieldPerson1.getPersonNo())); + } + + @Test + public void testZonedOffsetTime() throws SQLException { + assertEquals(fieldPerson1.getBirthDate().toInstant().atZone(ZoneId.systemDefault()).toOffsetDateTime().toOffsetTime(), + dao.getBirthDateZonedOffsetTime(fieldPerson1.getPersonNo())); + } + + @Test + public void testYearInt() throws SQLException { + final Val val = vals[0]; + assertEquals(Year.of((int)val.numVal), + dao.getYearInt(val.valNo) + ); + } + + @Test + public void testYearString() throws SQLException { + final Val val = vals[0]; + assertEquals(Year.parse(val.strVal), + dao.getYearString(val.valNo) + ); + } + + @Test + public void testZoneId() throws SQLException { + final Val val = vals[1]; + assertEquals(ZoneId.of(val.strVal), + dao.getZoneId(val.valNo) + ); + } + + @Test + public void testZoneOffsetInt() throws SQLException { + final Val val = vals[2]; + assertEquals(ZoneOffset.of(val.strVal), + dao.getZoneOffsetInt(val.valNo) + ); + } + + @Test + public void testZoneOffsetStr() throws SQLException { + final Val val = vals[2]; + assertEquals(ZoneOffset.ofHours((int)val.numVal), + dao.getZoneOffsetStr(val.valNo) + ); + } + + //IFJAVA8_END } diff --git a/jdbcmapper/src/test/java/com/moparisthebest/jdbc/codegen/PersonDAO.java b/jdbcmapper/src/test/java/com/moparisthebest/jdbc/codegen/PersonDAO.java index 31ca9d5..f6509c9 100644 --- a/jdbcmapper/src/test/java/com/moparisthebest/jdbc/codegen/PersonDAO.java +++ b/jdbcmapper/src/test/java/com/moparisthebest/jdbc/codegen/PersonDAO.java @@ -14,6 +14,7 @@ import java.sql.Timestamp; import java.util.*; //IFJAVA8_START import java.util.stream.Stream; +import java.time.*; //IFJAVA8_END /** @@ -165,4 +166,44 @@ public interface PersonDAO extends Closeable { @JdbcMapper.SQL("SELECT first_name FROM person WHERE person_no = {personNo}") FirstName getFirstNameEnum(long personNo) throws SQLException; + + //IFJAVA8_START + + @JdbcMapper.SQL("SELECT birth_date FROM person WHERE person_no = {personNo}") + Instant getBirthDateInstant(long personNo); + + @JdbcMapper.SQL("SELECT birth_date FROM person WHERE person_no = {personNo}") + LocalDateTime getBirthDateLocalDateTime(long personNo); + + @JdbcMapper.SQL("SELECT birth_date FROM person WHERE person_no = {personNo}") + LocalDate getBirthDateLocalDate(long personNo); + + @JdbcMapper.SQL("SELECT birth_date FROM person WHERE person_no = {personNo}") + LocalTime getBirthDateLocalTime(long personNo); + + @JdbcMapper.SQL("SELECT birth_date FROM person WHERE person_no = {personNo}") + ZonedDateTime getBirthDateZonedDateTime(long personNo); + + @JdbcMapper.SQL("SELECT birth_date FROM person WHERE person_no = {personNo}") + OffsetDateTime getBirthDateOffsetDateTime(long personNo); + + @JdbcMapper.SQL("SELECT birth_date FROM person WHERE person_no = {personNo}") + OffsetTime getBirthDateZonedOffsetTime(long personNo); + + @JdbcMapper.SQL("SELECT num_val FROM val WHERE val_no = {valNo}") + Year getYearInt(long valNo); + + @JdbcMapper.SQL("SELECT str_val FROM val WHERE val_no = {valNo}") + Year getYearString(long valNo); + + @JdbcMapper.SQL("SELECT str_val FROM val WHERE val_no = {valNo}") + ZoneId getZoneId(long valNo); + + @JdbcMapper.SQL("SELECT num_val FROM val WHERE val_no = {valNo}") + ZoneOffset getZoneOffsetInt(long valNo); + + @JdbcMapper.SQL("SELECT str_val FROM val WHERE val_no = {valNo}") + ZoneOffset getZoneOffsetStr(long valNo); + + //IFJAVA8_END } diff --git a/presto-sqlparser/src/test/java/com/moparisthebest/jdbc/codegen/PrestoPersonDAO.java b/presto-sqlparser/src/test/java/com/moparisthebest/jdbc/codegen/PrestoPersonDAO.java index 1603537..8543bc2 100644 --- a/presto-sqlparser/src/test/java/com/moparisthebest/jdbc/codegen/PrestoPersonDAO.java +++ b/presto-sqlparser/src/test/java/com/moparisthebest/jdbc/codegen/PrestoPersonDAO.java @@ -14,6 +14,7 @@ import java.sql.Timestamp; import java.util.*; //IFJAVA8_START import java.util.stream.Stream; +import java.time.*; //IFJAVA8_END /** @@ -165,4 +166,44 @@ public interface PrestoPersonDAO extends PersonDAO { @JdbcMapper.SQL("SELECT first_name FROM person WHERE person_no = {personNo}") FirstName getFirstNameEnum(long personNo) throws SQLException; + + //IFJAVA8_START + + @JdbcMapper.SQL("SELECT birth_date FROM person WHERE person_no = {personNo}") + Instant getBirthDateInstant(long personNo); + + @JdbcMapper.SQL("SELECT birth_date FROM person WHERE person_no = {personNo}") + LocalDateTime getBirthDateLocalDateTime(long personNo); + + @JdbcMapper.SQL("SELECT birth_date FROM person WHERE person_no = {personNo}") + LocalDate getBirthDateLocalDate(long personNo); + + @JdbcMapper.SQL("SELECT birth_date FROM person WHERE person_no = {personNo}") + LocalTime getBirthDateLocalTime(long personNo); + + @JdbcMapper.SQL("SELECT birth_date FROM person WHERE person_no = {personNo}") + ZonedDateTime getBirthDateZonedDateTime(long personNo); + + @JdbcMapper.SQL("SELECT birth_date FROM person WHERE person_no = {personNo}") + OffsetDateTime getBirthDateOffsetDateTime(long personNo); + + @JdbcMapper.SQL("SELECT birth_date FROM person WHERE person_no = {personNo}") + OffsetTime getBirthDateZonedOffsetTime(long personNo); + + @JdbcMapper.SQL("SELECT num_val FROM val WHERE val_no = {valNo}") + Year getYearInt(long valNo); + + @JdbcMapper.SQL("SELECT str_val FROM val WHERE val_no = {valNo}") + Year getYearString(long valNo); + + @JdbcMapper.SQL("SELECT str_val FROM val WHERE val_no = {valNo}") + ZoneId getZoneId(long valNo); + + @JdbcMapper.SQL("SELECT num_val FROM val WHERE val_no = {valNo}") + ZoneOffset getZoneOffsetInt(long valNo); + + @JdbcMapper.SQL("SELECT str_val FROM val WHERE val_no = {valNo}") + ZoneOffset getZoneOffsetStr(long valNo); + + //IFJAVA8_END } diff --git a/querymapper/src/main/java/com/moparisthebest/jdbc/CompilingRowToObjectMapper.java b/querymapper/src/main/java/com/moparisthebest/jdbc/CompilingRowToObjectMapper.java index b9be6f4..53fbd3e 100644 --- a/querymapper/src/main/java/com/moparisthebest/jdbc/CompilingRowToObjectMapper.java +++ b/querymapper/src/main/java/com/moparisthebest/jdbc/CompilingRowToObjectMapper.java @@ -458,6 +458,60 @@ public class CompilingRowToObjectMapper extends RowToObjectMapper { case TypeMappingsFactory.TYPE_READER: case TypeMappingsFactory.TYPE_STREAM: throw new MapperException("streaming return types are not supported by the JdbcControl; use ResultSet instead"); + // start java.time support + case TypeMappingsFactory.TYPE_INSTANT: + java.append("getInstant(").append(resultSetName).append(", ").append(String.valueOf(index)); + if(calendarName != null) + java.append(", ").append(calendarName); + java.append(")"); + return; + case TypeMappingsFactory.TYPE_LOCALDATETIME: + java.append("getLocalDateTime(").append(resultSetName).append(", ").append(String.valueOf(index)); + if(calendarName != null) + java.append(", ").append(calendarName); + java.append(")"); + return; + case TypeMappingsFactory.TYPE_LOCALDATE: + java.append("getLocalDate(").append(resultSetName).append(", ").append(String.valueOf(index)); + if(calendarName != null) + java.append(", ").append(calendarName); + java.append(")"); + return; + case TypeMappingsFactory.TYPE_LOCALTIME: + java.append("getLocalTime(").append(resultSetName).append(", ").append(String.valueOf(index)); + if(calendarName != null) + java.append(", ").append(calendarName); + java.append(")"); + return; + // todo: send in ZoneId here? + case TypeMappingsFactory.TYPE_ZONEDDATETIME: + java.append("getZonedDateTime(").append(resultSetName).append(", ").append(String.valueOf(index)); + if(calendarName != null) + java.append(", ").append(calendarName); + java.append(")"); + return; + case TypeMappingsFactory.TYPE_OFFSETDATETIME: + java.append("getOffsetDateTime(").append(resultSetName).append(", ").append(String.valueOf(index)); + if(calendarName != null) + java.append(", ").append(calendarName); + java.append(")"); + return; + case TypeMappingsFactory.TYPE_OFFSETTIME: + java.append("getOffsetTime(").append(resultSetName).append(", ").append(String.valueOf(index)); + if(calendarName != null) + java.append(", ").append(calendarName); + java.append(")"); + return; + case TypeMappingsFactory.TYPE_YEAR: + java.append("java.time.Year.parse(").append(resultSetName).append(".getString(").append(String.valueOf(index)).append("))"); + return; + case TypeMappingsFactory.TYPE_ZONEID: + java.append("java.time.ZoneId.of(").append(resultSetName).append(".getString(").append(String.valueOf(index)).append("))"); + return; + case TypeMappingsFactory.TYPE_ZONEOFFSET: + java.append("java.time.ZoneOffset.of(").append(resultSetName).append(".getString(").append(String.valueOf(index)).append("))"); + return; + // end java.time support case TypeMappingsFactory.TYPE_STRUCT: case TypeMappingsFactory.TYPE_UNKNOWN: // JAVA_TYPE (could be any), or REF diff --git a/querymapper/src/main/java/com/moparisthebest/jdbc/RowToObjectMapper.java b/querymapper/src/main/java/com/moparisthebest/jdbc/RowToObjectMapper.java index e6c944b..2e8f092 100644 --- a/querymapper/src/main/java/com/moparisthebest/jdbc/RowToObjectMapper.java +++ b/querymapper/src/main/java/com/moparisthebest/jdbc/RowToObjectMapper.java @@ -20,6 +20,7 @@ package com.moparisthebest.jdbc; */ import com.moparisthebest.jdbc.util.CaseInsensitiveHashMap; +import com.moparisthebest.jdbc.util.ResultSetUtil; import java.lang.reflect.*; import java.sql.ResultSet; @@ -30,6 +31,9 @@ import java.util.HashMap; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; +//IFJAVA8_START +import java.time.*; +//IFJAVA8_END import static com.moparisthebest.jdbc.UpdateableDTO.YES; import static com.moparisthebest.jdbc.UpdateableDTO.NO; @@ -629,6 +633,32 @@ public class RowToObjectMapper extends AbstractRowMapper { case TypeMappingsFactory.TYPE_READER: case TypeMappingsFactory.TYPE_STREAM: throw new MapperException("streaming return types are not supported by the JdbcControl; use ResultSet instead"); + //IFJAVA8_START + // start java.time support + case TypeMappingsFactory.TYPE_INSTANT: + return ResultSetUtil.getInstant(_resultSet, index, _cal); + case TypeMappingsFactory.TYPE_LOCALDATETIME: + return ResultSetUtil.getLocalDateTime(_resultSet, index, _cal); + case TypeMappingsFactory.TYPE_LOCALDATE: + return ResultSetUtil.getLocalDate(_resultSet, index, _cal); + case TypeMappingsFactory.TYPE_LOCALTIME: + return ResultSetUtil.getLocalTime(_resultSet, index, _cal); + // todo: send in ZoneId here? + case TypeMappingsFactory.TYPE_ZONEDDATETIME: + return ResultSetUtil.getZonedDateTime(_resultSet, index, _cal); + case TypeMappingsFactory.TYPE_OFFSETDATETIME: + return ResultSetUtil.getOffsetDateTime(_resultSet, index, _cal); + case TypeMappingsFactory.TYPE_OFFSETTIME: + return ResultSetUtil.getOffsetTime(_resultSet, index, _cal); + case TypeMappingsFactory.TYPE_YEAR: + // done this way instead of of(int) because usually int->string database coercion is allowed and the other isn't? + return Year.parse(_resultSet.getString(index)); + case TypeMappingsFactory.TYPE_ZONEID: + return ZoneId.of(_resultSet.getString(index)); + case TypeMappingsFactory.TYPE_ZONEOFFSET: + return ZoneOffset.of(_resultSet.getString(index)); + // end java.time support + //IFJAVA8_END case TypeMappingsFactory.TYPE_STRUCT: case TypeMappingsFactory.TYPE_UNKNOWN: // JAVA_TYPE (could be any), or REF diff --git a/querymapper/src/main/java/com/moparisthebest/jdbc/TypeMappingsFactory.java b/querymapper/src/main/java/com/moparisthebest/jdbc/TypeMappingsFactory.java index 3f2ab34..6be5654 100644 --- a/querymapper/src/main/java/com/moparisthebest/jdbc/TypeMappingsFactory.java +++ b/querymapper/src/main/java/com/moparisthebest/jdbc/TypeMappingsFactory.java @@ -29,15 +29,6 @@ import java.util.Map; public final class TypeMappingsFactory { private final static TypeMappingsFactory _instance = new TypeMappingsFactory(); - private static Class XMLBEANS_STRING_ENUM_ABSTRACT_BASE = null; - - static { - try { - XMLBEANS_STRING_ENUM_ABSTRACT_BASE = Class.forName("org.apache.xmlbeans.StringEnumAbstractBase"); - } catch (ClassNotFoundException e) { - // not an error, just means XmlBeans is not available - } - } /** * Get an instance of this class. @@ -79,7 +70,21 @@ public final class TypeMappingsFactory { public static final int TYPE_STRUCT = 29; public static final int TYPE_XMLBEAN_ENUM = 30; public static final int TYPE_ENUM = 31; - private static final int TYPE_MAX = TYPE_ENUM + 1; // should always reference the max + + // start java.time support + public static final int TYPE_INSTANT = 32; + public static final int TYPE_LOCALDATE = 33; + public static final int TYPE_LOCALDATETIME= 34; + public static final int TYPE_LOCALTIME = 35; + public static final int TYPE_OFFSETDATETIME = 36; + public static final int TYPE_OFFSETTIME = 37; + public static final int TYPE_YEAR = 38; + public static final int TYPE_ZONEDDATETIME = 39; + public static final int TYPE_ZONEID = 40; + public static final int TYPE_ZONEOFFSET = 41; + // end java.time support + + private static final int TYPE_MAX = TYPE_ZONEOFFSET + 1; // should always reference the max private final Map _primitiveDefaults; @@ -137,12 +142,31 @@ public final class TypeMappingsFactory { _typeMap.put(java.util.Date.class, TYPE_DATE); _typeMap.put(java.util.Calendar.class, TYPE_CALENDAR); _typeMap.put(java.util.GregorianCalendar.class, TYPE_CALENDAR); - if (XMLBEANS_STRING_ENUM_ABSTRACT_BASE != null) { - _typeMap.put(XMLBEANS_STRING_ENUM_ABSTRACT_BASE, TYPE_XMLBEAN_ENUM); - } + put("org.apache.xmlbeans.StringEnumAbstractBase", TYPE_XMLBEAN_ENUM); _typeMap.put(Enum.class, TYPE_ENUM); + + // start java.time support + put("java.time.Instant", TYPE_INSTANT); + put("java.time.LocalDate", TYPE_LOCALDATE); + put("java.time.LocalDateTime", TYPE_LOCALDATETIME); + put("java.time.LocalTime", TYPE_LOCALTIME); + put("java.time.OffsetDateTime", TYPE_OFFSETDATETIME); + put("java.time.OffsetTime", TYPE_OFFSETTIME); + put("java.time.Year", TYPE_YEAR); + put("java.time.ZonedDateTime", TYPE_ZONEDDATETIME); + put("java.time.ZoneId", TYPE_ZONEID); + put("java.time.ZoneOffset", TYPE_ZONEOFFSET); + // end java.time support } + private void put(final String className, final int type) { + try { + _typeMap.put(Class.forName(className), type); + } catch (ClassNotFoundException e) { + // not an error, just means this class is not available + } + } + /** * Get the type id (defined by this class) for the given class. * @param classType Class to get type of. diff --git a/querymapper/src/test/java/com/moparisthebest/jdbc/QueryMapperTest.java b/querymapper/src/test/java/com/moparisthebest/jdbc/QueryMapperTest.java index 9557c9c..b20ea19 100644 --- a/querymapper/src/test/java/com/moparisthebest/jdbc/QueryMapperTest.java +++ b/querymapper/src/test/java/com/moparisthebest/jdbc/QueryMapperTest.java @@ -13,6 +13,7 @@ import java.util.*; //IFJAVA8_START import java.util.stream.Collectors; import java.util.stream.Stream; +import java.time.*; //IFJAVA8_END import static com.moparisthebest.jdbc.TryClose.tryClose; @@ -36,7 +37,13 @@ public class QueryMapperTest { public static final Person fieldPerson3 = new FieldPerson(6, new Date(0), "Third", "Person"); public static final Person[] people = new Person[]{fieldPerson1, fieldPerson2, fieldPerson3}; - public static final Boss[] bosses =new Boss[]{fieldBoss1, fieldBoss2, fieldBoss3}; + public static final Boss[] bosses = new Boss[]{fieldBoss1, fieldBoss2, fieldBoss3}; + + public static final Val[] vals = new Val[]{ + new Val(1, 1969, "1969"), + new Val(2, 0, "America/New_York"), + new Val(3, -5, "-5"), + }; public static final Person setPerson1 = new SetPerson(fieldPerson1); public static final Boss setBoss1 = new SetBoss(fieldBoss1); @@ -82,12 +89,16 @@ public class QueryMapperTest { qm = new QueryMapper(conn); qm.executeUpdate("CREATE TABLE person (person_no NUMERIC, first_name VARCHAR(40), last_name VARCHAR(40), birth_date TIMESTAMP)"); qm.executeUpdate("CREATE TABLE boss (person_no NUMERIC, department VARCHAR(40))"); + qm.executeUpdate("CREATE TABLE val (val_no NUMERIC, num_val NUMERIC, str_val VARCHAR(40))"); for (final Person person : people) qm.executeUpdate("INSERT INTO person (person_no, birth_date, last_name, first_name) VALUES (?, ?, ?, ?)", person.getPersonNo(), person.getBirthDate(), person.getLastName(), person.getFirstName()); for (final Boss boss : bosses) { qm.executeUpdate("INSERT INTO person (person_no, birth_date, last_name, first_name) VALUES (?, ?, ?, ?)", boss.getPersonNo(), boss.getBirthDate(), boss.getLastName(), boss.getFirstName() == null ? boss.getFirst_name() : boss.getFirstName()); qm.executeUpdate("INSERT INTO boss (person_no, department) VALUES (?, ?)", boss.getPersonNo(), boss.getDepartment()); } + for (final Val val : vals) + qm.executeUpdate("INSERT INTO val (val_no, num_val, str_val) VALUES (?, ?, ?)", val.valNo, val.numVal, val.strVal); + } finally { tryClose(qm); tryClose(conn); @@ -436,4 +447,90 @@ public class QueryMapperTest { public void testEnum() throws SQLException { assertEquals(FirstName.First, qm.toObject("SELECT first_name FROM person WHERE person_no = ?", FirstName.class, fieldPerson1.getPersonNo())); } + + //IFJAVA8_START + + @Test + public void testInstant() throws SQLException { + assertEquals(fieldPerson1.getBirthDate().toInstant(), + qm.toObject("SELECT birth_date FROM person WHERE person_no = ?", Instant.class, fieldPerson1.getPersonNo())); + } + + @Test + public void testLocalDateTime() throws SQLException { + assertEquals(fieldPerson1.getBirthDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(), + qm.toObject("SELECT birth_date FROM person WHERE person_no = ?", LocalDateTime.class, fieldPerson1.getPersonNo())); + } + + @Test + public void testLocalDate() throws SQLException { + assertEquals(fieldPerson1.getBirthDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate(), + qm.toObject("SELECT birth_date FROM person WHERE person_no = ?", LocalDate.class, fieldPerson1.getPersonNo())); + } + + @Test + public void testLocalTime() throws SQLException { + assertEquals(fieldPerson1.getBirthDate().toInstant().atZone(ZoneId.systemDefault()).toLocalTime(), + qm.toObject("SELECT birth_date FROM person WHERE person_no = ?", LocalTime.class, fieldPerson1.getPersonNo())); + } + + @Test + public void testZonedDateTime() throws SQLException { + assertEquals(fieldPerson1.getBirthDate().toInstant().atZone(ZoneId.systemDefault()), + qm.toObject("SELECT birth_date FROM person WHERE person_no = ?", ZonedDateTime.class, fieldPerson1.getPersonNo())); + } + + @Test + public void testOffsetDateTime() throws SQLException { + assertEquals(fieldPerson1.getBirthDate().toInstant().atZone(ZoneId.systemDefault()).toOffsetDateTime(), + qm.toObject("SELECT birth_date FROM person WHERE person_no = ?", OffsetDateTime.class, fieldPerson1.getPersonNo())); + } + + @Test + public void testZonedOffsetTime() throws SQLException { + assertEquals(fieldPerson1.getBirthDate().toInstant().atZone(ZoneId.systemDefault()).toOffsetDateTime().toOffsetTime(), + qm.toObject("SELECT birth_date FROM person WHERE person_no = ?", OffsetTime.class, fieldPerson1.getPersonNo())); + } + + @Test + public void testYearInt() throws SQLException { + final Val val = vals[0]; + assertEquals(Year.of((int)val.numVal), + qm.toObject("SELECT num_val FROM val WHERE val_no = ?", Year.class, val.valNo) + ); + } + + @Test + public void testYearString() throws SQLException { + final Val val = vals[0]; + assertEquals(Year.parse(val.strVal), + qm.toObject("SELECT str_val FROM val WHERE val_no = ?", Year.class, val.valNo) + ); + } + + @Test + public void testZoneId() throws SQLException { + final Val val = vals[1]; + assertEquals(ZoneId.of(val.strVal), + qm.toObject("SELECT str_val FROM val WHERE val_no = ?", ZoneId.class, val.valNo) + ); + } + + @Test + public void testZoneOffsetInt() throws SQLException { + final Val val = vals[2]; + assertEquals(ZoneOffset.of(val.strVal), + qm.toObject("SELECT str_val FROM val WHERE val_no = ?", ZoneOffset.class, val.valNo) + ); + } + + @Test + public void testZoneOffsetStr() throws SQLException { + final Val val = vals[2]; + assertEquals(ZoneOffset.ofHours((int)val.numVal), + qm.toObject("SELECT num_val FROM val WHERE val_no = ?", ZoneOffset.class, val.valNo) + ); + } + + //IFJAVA8_END } diff --git a/querymapper/src/test/java/com/moparisthebest/jdbc/dto/Val.java b/querymapper/src/test/java/com/moparisthebest/jdbc/dto/Val.java new file mode 100644 index 0000000..3b1a76d --- /dev/null +++ b/querymapper/src/test/java/com/moparisthebest/jdbc/dto/Val.java @@ -0,0 +1,15 @@ +package com.moparisthebest.jdbc.dto; + +/** + * Created by mopar on 6/14/17. + */ +public class Val { + public final long valNo, numVal; + public final String strVal; + + public Val(final long valNo, final long numVal, final String strVal) { + this.valNo = valNo; + this.numVal = numVal; + this.strVal = strVal; + } +}