-
Notifications
You must be signed in to change notification settings - Fork 74
The MySQL plugin compare server and client timezone #106
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 7 commits
434f403
9a3fd65
a30a169
98a2bec
a8ad95b
091d65c
14b8b5e
6ba1f85
14f82b0
275dbf3
9a03bcf
eb2ae73
c333c7d
21adf05
7ca3a9b
dd2c693
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package org.embulk.input; | ||
|
||
import java.sql.Connection; | ||
import java.sql.ResultSet; | ||
import java.sql.SQLException; | ||
import java.sql.Statement; | ||
import java.util.Locale; | ||
import java.util.TimeZone; | ||
|
||
public class MySQLTimeZoneBuilder | ||
{ | ||
private static final int ONE_HOUR_SEC = 3600; | ||
private static final int ONE_MIN_SEC = 60; | ||
|
||
public static TimeZone fromSystemTimeZone(Connection connection) | ||
throws SQLException | ||
{ | ||
// | ||
// First, I used `@@system_time_zone`. but It return non Time Zone Abbreviations name on a specific platform. | ||
// So, This method calculate GMT offset with query. | ||
// | ||
String query = "select TIME_TO_SEC(timediff(now(),utc_timestamp()));"; | ||
Statement stmt = connection.createStatement(); | ||
ResultSet rs = stmt.executeQuery(query); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Statement stmt = ... try { ... } finally { stmt.close(); } There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add |
||
|
||
if (rs.next()) { | ||
int offset_seconds = rs.getInt(1); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Class names, method names and variable names (except for constant names) should be CamelCased in Java. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Variable names use camel case like |
||
return fromGMTOffsetSeconds(offset_seconds); | ||
} | ||
else { | ||
// TODO Error check. | ||
return null; | ||
} | ||
} | ||
|
||
public static TimeZone fromGMTOffsetSeconds(int offset_seconds) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it necessary to be public? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change to |
||
{ | ||
if( offset_seconds == 0 ) { | ||
return TimeZone.getTimeZone("UTC"); | ||
} | ||
|
||
String sign = offset_seconds > 0 ? "+" : "-"; | ||
int abs_offset_sec = Math.abs(offset_seconds); | ||
int tz_hour = abs_offset_sec / ONE_HOUR_SEC; | ||
int tz_min = abs_offset_sec % ONE_HOUR_SEC / ONE_MIN_SEC; | ||
String tz_name = String.format(Locale.ENGLISH, "GMT%s%02d:%02d", sign, tz_hour, tz_min); | ||
return TimeZone.getTimeZone(tz_name); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does it work for summer time? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As discussed on the Twitter, I used TimeZone clientTimeZone = TimeZone.getDefault();
Date today = new Date();
int clientOffset = clientTimeZone.getRawOffset();
if( clientTimeZone.inDaylightTime(today) ){
clientOffset += clientTimeZone.getDSTSavings();
} |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,17 @@ | ||
package org.embulk.input.mysql; | ||
|
||
import java.sql.Statement; | ||
import java.util.List; | ||
import java.sql.Connection; | ||
import java.sql.PreparedStatement; | ||
import java.sql.SQLException; | ||
import java.sql.ResultSet; | ||
import java.util.Locale; | ||
import java.util.TimeZone; | ||
|
||
import com.mysql.jdbc.ConnectionImpl; | ||
import com.mysql.jdbc.ConnectionProperties; | ||
import org.embulk.input.MySQLTimeZoneBuilder; | ||
import org.embulk.input.jdbc.JdbcInputConnection; | ||
import org.embulk.input.jdbc.JdbcLiteral; | ||
import org.embulk.input.jdbc.getter.ColumnGetter; | ||
|
@@ -59,4 +62,31 @@ public TimeZone getServerTimezoneTZ() | |
{ | ||
return ((ConnectionImpl) connection).getServerTimezoneTZ(); | ||
} | ||
|
||
@Override | ||
public void before_load() | ||
throws SQLException | ||
{ | ||
// TODO error check. | ||
TimeZone svr_tz = MySQLTimeZoneBuilder.fromSystemTimeZone(connection); | ||
|
||
String usr_tz_name = System.getProperty("user.timezone"); | ||
TimeZone usr_tz = TimeZone.getTimeZone(usr_tz_name); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can get same value by There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Changed to |
||
|
||
// | ||
// Compare offset only. Although I expect to return true, the following code return false, | ||
// | ||
// TimeZone tz_jst = TimeZone.getTimeZone("JST"); | ||
// TimeZone tz_gmt9 = TimeZone.getTimeZone("GMT+9"); | ||
// tz_jst.hasSameRules(tz_gmt9) // return false. | ||
// | ||
if( svr_tz.getRawOffset() != usr_tz.getRawOffset() ) { | ||
logger.warn(String.format(Locale.ENGLISH, | ||
"The server timezone offset(%s) and client timezone(%s) has different timezone offset. The plugin will fetch wrong datetime values.",svr_tz.getID(),usr_tz_name)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about following message? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Changed to |
||
logger.warn(String.format(Locale.ENGLISH, | ||
"Use `options: { useLegacyDatetimeCode: false }`")); | ||
} | ||
logger.warn(String.format(Locale.ENGLISH,"The plugin will set `useLegacyDatetimeCode=false` by default in future.")); | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
newConnection
is called byAbstractJdbcInputPlugin#transaction
first, then called byAbstractJdbcInputPlugin#run
.So we should check timezone in the
transaction
method.Now
setupTask
method isprivate
, but I think the method is appropriate to check timezone if it is changed toprotected
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed setupTask to
protect
and OverridesetupTask
like the below.