You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by st...@apache.org on 2019/01/25 18:11:57 UTC

[openjpa] 02/04: OPENJPA-2713 add OffsetTime support

This is an automated email from the ASF dual-hosted git repository.

struberg pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openjpa.git

commit dbfb360e85bb29bb11f87e3d5406a4edd4e51bd3
Author: Mark Struberg <st...@apache.org>
AuthorDate: Tue Jan 22 22:07:32 2019 +0100

    OPENJPA-2713 add OffsetTime support
    
    Works, but something is a bit fishy still.
---
 .../apache/openjpa/jdbc/sql/AbstractResult.java    | 32 +++++++++++++
 .../org/apache/openjpa/jdbc/sql/DBDictionary.java  | 53 ++++++++++++++++++++++
 .../org/apache/openjpa/jdbc/sql/MergedResult.java  | 12 +++++
 .../java/org/apache/openjpa/jdbc/sql/Result.java   | 14 ++++++
 .../apache/openjpa/jdbc/sql/ResultSetResult.java   | 17 +++++++
 .../openjpa/persistence/simple/Java8TimeTypes.java | 20 ++++++++
 .../persistence/simple/TestJava8TimeTypes.java     |  7 ++-
 7 files changed, 154 insertions(+), 1 deletion(-)

diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/AbstractResult.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/AbstractResult.java
index ab925f1..8b2a01a 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/AbstractResult.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/AbstractResult.java
@@ -34,6 +34,8 @@ import java.sql.Types;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
+import java.time.OffsetDateTime;
+import java.time.OffsetTime;
 import java.util.Calendar;
 import java.util.Date;
 import java.util.HashMap;
@@ -562,6 +564,36 @@ public abstract class AbstractResult
     }
 
     @Override
+    public OffsetTime getOffsetTime(Object obj) throws SQLException {
+        return getOffsetTimeInternal(translate(obj, null), null);
+    }
+
+    protected OffsetTime getOffsetTimeInternal(Object obj, Joins joins) throws SQLException {
+        Object val = checkNull(getObjectInternal(obj, JavaTypes.OFFSET_TIME, null, joins));
+        if (val == null)
+            return null;
+        if (val instanceof OffsetTime)
+            return (OffsetTime) val;
+
+        return OffsetTime.parse(val.toString());
+    }
+
+    @Override
+    public OffsetDateTime getOffsetDateTime(Object obj) throws SQLException {
+        return getOffsetDateTimeInternal(translate(obj, null), null);
+    }
+
+    protected OffsetDateTime getOffsetDateTimeInternal(Object obj, Joins joins) throws SQLException {
+        Object val = checkNull(getObjectInternal(obj, JavaTypes.OFFSET_DATETIME, null, joins));
+        if (val == null)
+            return null;
+        if (val instanceof OffsetDateTime)
+            return (OffsetDateTime) val;
+
+        return OffsetDateTime.parse(val.toString());
+    }
+
+    @Override
     public char getChar(Object obj)
         throws SQLException {
         return getCharInternal(translate(obj, null), null);
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java
index 81d249f..0fe52d5 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java
@@ -48,6 +48,10 @@ import java.text.MessageFormat;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
+import java.time.OffsetDateTime;
+import java.time.OffsetTime;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Calendar;
@@ -805,6 +809,24 @@ public class DBDictionary
         return tst != null ? tst.toLocalDateTime() : null;
     }
 
+    /**
+     * Retrieve the specified column of the SQL ResultSet to the proper
+     * {@link OffsetTime} java type.
+     */
+    public OffsetTime getOffsetTime(ResultSet rs, int column) throws SQLException {
+        java.sql.Time time = rs.getTime(column);
+        return time != null ? time.toLocalTime().atOffset(OffsetDateTime.now().getOffset()) : null;
+    }
+
+    /**
+     * Retrieve the specified column of the SQL ResultSet to the proper
+     * {@link OffsetDateTime} java type.
+     */
+    public OffsetDateTime getOffsetDateTime(ResultSet rs, int column) throws SQLException {
+        Timestamp tst = rs.getTimestamp(column);
+        return tst != null ? tst.toLocalDateTime().atOffset(OffsetDateTime.now().getOffset()) : null;
+    }
+
     private ProxyManager getProxyManager() {
         if (_proxyManager == null) {
             _proxyManager = conf.getProxyManagerInstance();
@@ -1242,6 +1264,31 @@ public class DBDictionary
         setTimestamp(stmnt, idx, java.sql.Timestamp.valueOf(val), null, col);
     }
 
+
+    /**
+     * Set the given LocalTime value as a parameter to the statement.
+     *
+     */
+    public void setOffsetTime(PreparedStatement stmnt, int idx, OffsetTime val, Column col)
+            throws SQLException {
+        // adjust to the default timezone right now.
+        // This is an ugly hack and cries for troubles in case the daylight saving changes...
+        // Which is also the reason why we cannot cache the offset.
+        // According to the Oracle docs the JDBC driver always assumes 'local time' ...
+        LocalTime localTime = val.withOffsetSameInstant(OffsetDateTime.now().getOffset()).toLocalTime();
+        setLocalTime(stmnt, idx, localTime, col);
+    }
+
+    /**
+     * Set the given LocalTime value as a parameter to the statement.
+     *
+     */
+    public void setOffsetDateTime(PreparedStatement stmnt, int idx, OffsetDateTime val, Column col)
+            throws SQLException {
+        LocalDateTime localdt = val.atZoneSameInstant(ZoneId.systemDefault()).toLocalDateTime();
+        setLocalDateTime(stmnt, idx, localdt, col);
+    }
+
     /**
      * Set the given value as a parameter to the statement.
      */
@@ -1461,6 +1508,12 @@ public class DBDictionary
             case JavaTypes.LOCAL_DATETIME:
                 setLocalDateTime(stmnt, idx, (LocalDateTime) val, col);
                 break;
+            case JavaTypes.OFFSET_TIME:
+                setOffsetTime(stmnt, idx, (OffsetTime) val, col);
+                break;
+            case JavaTypes.OFFSET_DATETIME:
+                setOffsetDateTime(stmnt, idx, (OffsetDateTime) val, col);
+                break;
             case JavaTypes.BIGDECIMAL:
                 setBigDecimal(stmnt, idx, (BigDecimal) val, col);
                 break;
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/MergedResult.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/MergedResult.java
index c22539e..237cc73 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/MergedResult.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/MergedResult.java
@@ -32,6 +32,8 @@ import java.sql.Timestamp;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
+import java.time.OffsetDateTime;
+import java.time.OffsetTime;
 import java.util.Calendar;
 import java.util.Comparator;
 import java.util.Date;
@@ -355,6 +357,16 @@ public class MergedResult implements Result {
     }
 
     @Override
+    public OffsetTime getOffsetTime(Object obj) throws SQLException {
+        return _res[_idx].getOffsetTime(obj);
+    }
+
+    @Override
+    public OffsetDateTime getOffsetDateTime(Object obj) throws SQLException {
+        return _res[_idx].getOffsetDateTime(obj);
+    }
+
+    @Override
     public char getChar(Object obj)
         throws SQLException {
         return _res[_idx].getChar(obj);
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Result.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Result.java
index 35abde7..8f28a33 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Result.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Result.java
@@ -32,6 +32,8 @@ import java.sql.Timestamp;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
+import java.time.OffsetDateTime;
+import java.time.OffsetTime;
 import java.util.Calendar;
 import java.util.Date;
 import java.util.Locale;
@@ -306,6 +308,18 @@ public interface Result
     /**
      * Return the value stored in the given column or id.
      */
+    OffsetTime getOffsetTime(Object obj)
+        throws SQLException;
+
+    /**
+     * Return the value stored in the given column or id.
+     */
+    OffsetDateTime getOffsetDateTime(Object obj)
+        throws SQLException;
+
+    /**
+     * Return the value stored in the given column or id.
+     */
     char getChar(Object obj)
         throws SQLException;
 
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/ResultSetResult.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/ResultSetResult.java
index 143c524..ee7ddd3 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/ResultSetResult.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/ResultSetResult.java
@@ -36,6 +36,8 @@ import java.sql.Types;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
+import java.time.OffsetDateTime;
+import java.time.OffsetTime;
 import java.util.Calendar;
 import java.util.Date;
 import java.util.Locale;
@@ -338,6 +340,17 @@ public class ResultSetResult
         return _dict.getLocalDateTime(_rs, ((Number) obj).intValue());
     }
 
+    @Override
+    protected OffsetTime getOffsetTimeInternal(Object obj, Joins joins)
+            throws SQLException {
+        return _dict.getOffsetTime(_rs, ((Number) obj).intValue());
+    }
+
+    @Override
+    protected OffsetDateTime getOffsetDateTimeInternal(Object obj, Joins joins)
+            throws SQLException {
+        return _dict.getOffsetDateTime(_rs, ((Number) obj).intValue());
+    }
 
     @Override
     protected char getCharInternal(Object obj, Joins joins)
@@ -466,6 +479,10 @@ public class ResultSetResult
                 return getLocalTimeInternal(obj, joins);
             case JavaTypes.LOCAL_DATETIME:
                 return getLocalDateTimeInternal(obj, joins);
+            case JavaTypes.OFFSET_TIME:
+                return getOffsetTimeInternal(obj, joins);
+            case JavaTypes.OFFSET_DATETIME:
+                return getOffsetDateTimeInternal(obj, joins);
             case JavaTypes.BIGDECIMAL:
                 return getBigDecimalInternal(obj, joins);
             case JavaTypes.NUMBER:
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/Java8TimeTypes.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/Java8TimeTypes.java
index d5b1681..bfce8e3 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/Java8TimeTypes.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/Java8TimeTypes.java
@@ -23,6 +23,8 @@ import javax.persistence.Id;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
+import java.time.OffsetDateTime;
+import java.time.OffsetTime;
 import java.util.Date;
 
 /**
@@ -39,6 +41,8 @@ public class Java8TimeTypes {
     private LocalTime localTimeField;
     private LocalDate localDateField;
     private LocalDateTime localDateTimeField;
+    private OffsetTime offsetTimeField;
+    private OffsetDateTime offsetDateTimeField;
 
     public int getId() {
         return id;
@@ -79,4 +83,20 @@ public class Java8TimeTypes {
     public void setLocalDateTimeField(LocalDateTime localDateTimeField) {
         this.localDateTimeField = localDateTimeField;
     }
+
+    public OffsetTime getOffsetTimeField() {
+        return offsetTimeField;
+    }
+
+    public void setOffsetTimeField(OffsetTime offsetTimeField) {
+        this.offsetTimeField = offsetTimeField;
+    }
+
+    public OffsetDateTime getOffsetDateTimeField() {
+        return offsetDateTimeField;
+    }
+
+    public void setOffsetDateTimeField(OffsetDateTime offsetDateTimeField) {
+        this.offsetDateTimeField = offsetDateTimeField;
+    }
 }
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/TestJava8TimeTypes.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/TestJava8TimeTypes.java
index 3de2258..8175036 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/TestJava8TimeTypes.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/TestJava8TimeTypes.java
@@ -24,6 +24,7 @@ import javax.persistence.EntityManager;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
+import java.time.ZoneOffset;
 import java.util.Date;
 
 /**
@@ -31,7 +32,7 @@ import java.util.Date;
  */
 public class TestJava8TimeTypes extends SingleEMFTestCase {
     private static String VAL_LOCAL_DATE = "2019-01-01";
-    private static String VAL_LOCAL_TIME = "14:57:15";
+    private static String VAL_LOCAL_TIME = "04:57:15";
     private static String VAL_LOCAL_DATETIME = "2019-01-01T01:00:00";
 
     @Override
@@ -48,6 +49,8 @@ public class TestJava8TimeTypes extends SingleEMFTestCase {
         e.setLocalTimeField(LocalTime.parse(VAL_LOCAL_TIME));
         e.setLocalDateField(LocalDate.parse(VAL_LOCAL_DATE));
         e.setLocalDateTimeField(LocalDateTime.parse(VAL_LOCAL_DATETIME));
+        e.setOffsetTimeField(e.getLocalTimeField().atOffset(ZoneOffset.ofHours(-9)));
+        e.setOffsetDateTimeField(e.getLocalDateTimeField().atOffset(ZoneOffset.ofHours(-9)));
 
         em.persist(e);
         em.getTransaction().commit();
@@ -60,6 +63,8 @@ public class TestJava8TimeTypes extends SingleEMFTestCase {
         assertEquals(LocalTime.parse(VAL_LOCAL_TIME), eRead.getLocalTimeField());
         assertEquals(LocalDate.parse(VAL_LOCAL_DATE), eRead.getLocalDateField());
         assertEquals(LocalDateTime.parse(VAL_LOCAL_DATETIME), eRead.getLocalDateTimeField());
+        assertEquals(e.getOffsetTimeField(), eRead.getOffsetTimeField());
+        assertEquals(e.getOffsetDateTimeField(), eRead.getOffsetDateTimeField());
     }
 
 }