Merge lp:~massimo-siani/mariadb-java-client/CONJ-86 into lp:mariadb-java-client

Proposed by Massimo Siani
Status: Needs review
Proposed branch: lp:~massimo-siani/mariadb-java-client/CONJ-86
Merge into: lp:mariadb-java-client
Diff against target: 136 lines (+106/-1)
2 files modified
src/main/java/org/mariadb/jdbc/internal/common/AbstractValueObject.java (+13/-1)
src/test/java/org/mariadb/jdbc/TimestampTest.java (+93/-0)
To merge this branch: bzr merge lp:~massimo-siani/mariadb-java-client/CONJ-86
Reviewer Review Type Date Requested Status
Maria-captains Pending
Review via email: mp+224263@code.launchpad.net

Commit message

Fix for CONJ-86

Description of the change

CONJ-86:
It seems that the getTimestamp of the ResultSet class use the default client timestamp for time conversions. This works in most cases, but when Daylight Saving Time is used, it fails at certain times.

Proposed solution: if an exception is thrown while parsing the timestamp, and no explicit calendar has been set, try with UTC. Otherwise, works as before (throws the exception).

To post a comment you must log in.
513. By Massimo Siani

Merge changes from trunk and retest

Unmerged revisions

513. By Massimo Siani

Merge changes from trunk and retest

512. By Massimo Siani

If a calendar has been given, do not try with UTC

511. By Massimo Siani

Fix for CONJ-86

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/main/java/org/mariadb/jdbc/internal/common/AbstractValueObject.java'
--- src/main/java/org/mariadb/jdbc/internal/common/AbstractValueObject.java 2014-03-25 17:00:46 +0000
+++ src/main/java/org/mariadb/jdbc/internal/common/AbstractValueObject.java 2014-07-07 10:12:18 +0000
@@ -52,6 +52,7 @@
52import org.mariadb.jdbc.MySQLBlob;52import org.mariadb.jdbc.MySQLBlob;
53import org.mariadb.jdbc.MySQLClob;53import org.mariadb.jdbc.MySQLClob;
54import org.mariadb.jdbc.internal.mysql.MySQLType;54import org.mariadb.jdbc.internal.mysql.MySQLType;
55
55import java.io.ByteArrayInputStream;56import java.io.ByteArrayInputStream;
56import java.io.InputStream;57import java.io.InputStream;
57import java.io.UnsupportedEncodingException;58import java.io.UnsupportedEncodingException;
@@ -61,6 +62,7 @@
61import java.text.ParseException;62import java.text.ParseException;
62import java.text.SimpleDateFormat;63import java.text.SimpleDateFormat;
63import java.util.Calendar;64import java.util.Calendar;
65import java.util.TimeZone;
6466
6567
66public abstract class AbstractValueObject implements ValueObject {68public abstract class AbstractValueObject implements ValueObject {
@@ -259,7 +261,17 @@
259 if (cal != null) {261 if (cal != null) {
260 sdf.setCalendar(cal);262 sdf.setCalendar(cal);
261 }263 }
262 final java.util.Date utilTime = sdf.parse(rawValue);264 java.util.Date utilTime;
265 try {
266 utilTime = sdf.parse(rawValue);
267 } catch (ParseException pe) {
268 if (cal == null) {
269 sdf.setCalendar(Calendar.getInstance(TimeZone.getTimeZone("UTC")));
270 utilTime = sdf.parse(rawValue);
271 } else {
272 throw pe;
273 }
274 }
263 Timestamp ts = new Timestamp(utilTime.getTime());275 Timestamp ts = new Timestamp(utilTime.getTime());
264 if(rawValue.indexOf('.') != -1) {276 if(rawValue.indexOf('.') != -1) {
265 ts.setNanos(extractNanos(rawValue));277 ts.setNanos(extractNanos(rawValue));
266278
=== added file 'src/test/java/org/mariadb/jdbc/TimestampTest.java'
--- src/test/java/org/mariadb/jdbc/TimestampTest.java 1970-01-01 00:00:00 +0000
+++ src/test/java/org/mariadb/jdbc/TimestampTest.java 2014-07-07 10:12:18 +0000
@@ -0,0 +1,93 @@
1package org.mariadb.jdbc;
2
3import static org.junit.Assert.*;
4
5import java.sql.PreparedStatement;
6import java.sql.ResultSet;
7import java.sql.SQLException;
8import java.sql.Statement;
9import java.sql.Timestamp;
10import java.util.Calendar;
11import java.util.Locale;
12import java.util.TimeZone;
13
14import org.junit.After;
15import org.junit.Before;
16import org.junit.Test;
17
18public class TimestampTest extends BaseTest {
19
20 private Statement stmt;
21 private Locale previousFormatLocale;
22 private TimeZone previousTimeZone;
23 private TimeZone swedishTimeZone;
24 private String prevTimeZone;
25
26 @Before
27 public void setUp() throws SQLException {
28 //Save the previous FORMAT locate so we can restore it later
29 previousFormatLocale = Locale.getDefault(Locale.Category.FORMAT);
30 //Save the previous timezone so we can restore it later
31 previousTimeZone = TimeZone.getDefault();
32
33 swedishTimeZone = TimeZone.getTimeZone("Europe/Stockholm");
34 TimeZone.setDefault(swedishTimeZone); //Everybody running this test case should be in Sweden
35
36 stmt = connection.createStatement();
37
38 ResultSet rs = stmt.executeQuery("SELECT @@time_zone");
39 rs.next();
40 prevTimeZone = rs.getString(1);
41 rs.close();
42 stmt.execute("SET time_zone = '+00:00'");
43 stmt.execute("drop table if exists timestamptest");
44 stmt.execute("create table timestamptest (id int not null primary key auto_increment, tm timestamp)");
45 }
46
47 @After
48 public void tearDown() throws SQLException {
49 //Reset the FORMAT locate so other test cases are not disturbed.
50 Locale.setDefault(Locale.Category.FORMAT, previousFormatLocale);
51 //Reset the timezone so so other test cases are not disturbed.
52 TimeZone.setDefault(previousTimeZone);
53 stmt.execute("SET time_zone = '" + prevTimeZone + "'");
54 }
55
56
57 @Test
58 public void testGetTimestamp() throws SQLException {
59 Calendar _20140101_1320_59 = Calendar.getInstance(TimeZone.getTimeZone("utc"));
60 _20140101_1320_59.clear();
61 _20140101_1320_59.set(2014, 0, 1, 13, 20, 59);
62
63 PreparedStatement ps = connection.prepareStatement("insert into timestamptest values(1, ?)");
64 ps.setTimestamp(1, new Timestamp(_20140101_1320_59.getTimeInMillis()));
65 ps.execute();
66
67 ResultSet rs = stmt.executeQuery("select * from timestamptest");
68 while(rs.next()) {
69 Timestamp timestamp = rs.getTimestamp(2);
70 assertEquals(_20140101_1320_59.getTimeInMillis(), timestamp.getTime());
71 }
72 }
73
74 @Test
75 public void testGetTimestampWhenDaylightSavingRemovesHour() throws SQLException {
76 //The time 2014-03-30 01:15:00 is valid in UTC
77 Calendar quaterPastTwo30thOfMarth2014 = Calendar.getInstance(TimeZone.getTimeZone("utc"));
78 quaterPastTwo30thOfMarth2014.clear();
79 quaterPastTwo30thOfMarth2014.set(2014, 2, 30, 2, 15, 0);
80
81 PreparedStatement ps = connection.prepareStatement("insert into timestamptest values(1, ?)");
82 //Explicitly set a time that does not exists in Swedish timezone
83 //Note: this query will only work if the server is set to UTC (set time_zone = '+00:00' above)
84 ps.setString(1, "2014-03-30 02:15:00");
85 ps.execute();
86
87 ResultSet rs = stmt.executeQuery("select * from timestamptest");
88 while(rs.next()) {
89 Timestamp timestamp = rs.getTimestamp(2);
90 assertEquals(quaterPastTwo30thOfMarth2014.getTimeInMillis(), timestamp.getTime());
91 }
92 }
93}

Subscribers

People subscribed via source and target branches