embulk-output-mysql 0.7.8 → 0.7.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 97ce26c6892e8428a757a29cfcf1635d37d5ed2e
4
- data.tar.gz: 6daf806203e0a6204cd3f69f4b34f012422cd3a6
3
+ metadata.gz: 08449007dfa072591724efe96735f7f36e47890f
4
+ data.tar.gz: 39acd32a644c1a5dfec133f5d5d5705d6653b6a1
5
5
  SHA512:
6
- metadata.gz: b737ebe4debbc5657a998fbceb3e3d5355ea9a041a2d8a6c5193a68611f03968a888f79c71f13a5a024385818ead1ec9e180403511608fc735aeaf42a61e36bf
7
- data.tar.gz: 40a5b20c6126b885394eaf7e883a7f4be05ef18396e79946bef23a77766bf6c3422571b8b774ee697dc7ac1efdfd133eea189efe8bd7bee405ab5f8ef5534ff4
6
+ metadata.gz: fdc887a07cda0ab68e9e00013ea3c0be5e480647728476a9f0ae9f847bc197ce12684d120eea627f622af54efdba7d38baf94b9f0202a2c9f4e30fc9bf736201
7
+ data.tar.gz: b5f443bdc839934d3c2db7d4f8fb699eb50b2b8ef618c8eb2efd2a6d491db4fdaf6fa16dcde7a75d8d31302bd1a8e12e5cd921846bc701ee3de9845ddbd2a322
data/README.md CHANGED
@@ -15,6 +15,7 @@ MySQL output plugin for Embulk loads records to MySQL.
15
15
  - **user**: database login user name (string, required)
16
16
  - **password**: database login password (string, default: "")
17
17
  - **database**: destination database name (string, required)
18
+ - **temp_database**: database name for intermediate tables. by default, intermediate tables will be created in the database specified by `database`. (string, optional)
18
19
  - **table**: destination table name (string, required)
19
20
  - **options**: extra connection properties (hash, default: {})
20
21
  - **retry_limit** max retry count for database operations (integer, default: 12)
@@ -3,14 +3,20 @@ package org.embulk.output;
3
3
  import java.util.Properties;
4
4
  import java.io.IOException;
5
5
  import java.sql.SQLException;
6
+
6
7
  import com.google.common.base.Optional;
8
+
7
9
  import org.embulk.config.Config;
8
10
  import org.embulk.config.ConfigDefault;
9
11
  import org.embulk.output.jdbc.AbstractJdbcOutputPlugin;
10
12
  import org.embulk.output.jdbc.BatchInsert;
13
+ import org.embulk.output.jdbc.JdbcOutputConnection;
11
14
  import org.embulk.output.jdbc.MergeConfig;
15
+ import org.embulk.output.jdbc.TableIdentifier;
16
+ import org.embulk.output.mysql.MySQLOutputConnection;
12
17
  import org.embulk.output.mysql.MySQLOutputConnector;
13
18
  import org.embulk.output.mysql.MySQLBatchInsert;
19
+ import org.embulk.spi.Schema;
14
20
 
15
21
  public class MySQLOutputPlugin
16
22
  extends AbstractJdbcOutputPlugin
@@ -34,6 +40,10 @@ public class MySQLOutputPlugin
34
40
 
35
41
  @Config("database")
36
42
  public String getDatabase();
43
+
44
+ @Config("temp_database")
45
+ @ConfigDefault("null")
46
+ public Optional<String> getTempDatabase();
37
47
  }
38
48
 
39
49
  @Override
@@ -103,6 +113,15 @@ public class MySQLOutputPlugin
103
113
  return new MySQLOutputConnector(url, props);
104
114
  }
105
115
 
116
+ @Override
117
+ protected TableIdentifier buildIntermediateTableId(JdbcOutputConnection con, PluginTask task, String tableName) {
118
+ MySQLPluginTask t = (MySQLPluginTask) task;
119
+ if (t.getTempDatabase().isPresent()) {
120
+ return new TableIdentifier(t.getTempDatabase().get(), null, tableName);
121
+ }
122
+ return super.buildIntermediateTableId(con, task, tableName);
123
+ }
124
+
106
125
  @Override
107
126
  protected BatchInsert newBatchInsert(PluginTask task, Optional<MergeConfig> mergeConfig) throws IOException, SQLException
108
127
  {
@@ -122,4 +141,13 @@ public class MySQLOutputPlugin
122
141
  return false;
123
142
  }
124
143
  }
144
+
145
+ @Override
146
+ protected void doBegin(JdbcOutputConnection con,
147
+ PluginTask task, final Schema schema, int taskCount) throws SQLException
148
+ {
149
+ MySQLOutputConnection mySQLCon = (MySQLOutputConnection)con;
150
+ mySQLCon.compareTimeZone();
151
+ super.doBegin(con,task,schema,taskCount);
152
+ }
125
153
  }
@@ -0,0 +1,107 @@
1
+ package org.embulk.output;
2
+
3
+ import org.embulk.spi.Exec;
4
+ import org.slf4j.Logger;
5
+
6
+
7
+ import java.sql.Connection;
8
+ import java.sql.ResultSet;
9
+ import java.sql.SQLException;
10
+ import java.sql.Statement;
11
+ import java.util.Date;
12
+ import java.util.Locale;
13
+ import java.util.TimeZone;
14
+
15
+ public class MySQLTimeZoneComparison {
16
+
17
+ private static final int ONE_HOUR_SEC = 3600;
18
+ private static final int ONE_MIN_SEC = 60;
19
+
20
+ private Connection connection;
21
+
22
+ private final Logger logger = Exec.getLogger(getClass());
23
+
24
+ public MySQLTimeZoneComparison(Connection connection)
25
+ {
26
+ this.connection = connection;
27
+ }
28
+
29
+ public void compareTimeZone()
30
+ throws SQLException
31
+ {
32
+ TimeZone serverTimeZone = null;
33
+ try {
34
+ serverTimeZone = getServerTimeZone();
35
+ }
36
+ catch (SQLException ex) {
37
+ logger.warn("Can't get server TimeZone.");
38
+ logger.warn(String.format(Locale.ENGLISH, "SQLException raised %s", ex.toString()));
39
+ }
40
+
41
+ TimeZone clientTimeZone = TimeZone.getDefault();
42
+ Date today = new Date();
43
+ int clientOffset = clientTimeZone.getRawOffset();
44
+
45
+ if (clientTimeZone.inDaylightTime(today)) {
46
+ clientOffset += clientTimeZone.getDSTSavings();
47
+ }
48
+
49
+ //
50
+ // Compare offset only. Although I expect to return true, the following code return false,
51
+ //
52
+ // TimeZone tz_jst = TimeZone.getTimeZone("JST");
53
+ // TimeZone tz_gmt9 = TimeZone.getTimeZone("GMT+9");
54
+ // tz_jst.hasSameRules(tz_gmt9) // return false.
55
+ //
56
+ if (clientOffset != serverTimeZone.getRawOffset()) {
57
+ logger.warn(String.format(Locale.ENGLISH,
58
+ "The client timezone(%s) is different from the server timezone(%s). The plugin will store wrong datetime values.",
59
+ clientTimeZone.getID(), serverTimeZone.getID()));
60
+ logger.warn(String.format(Locale.ENGLISH,
61
+ "You may need to set options `useLegacyDatetimeCode` and `serverTimezone`"));
62
+ logger.warn(String.format(Locale.ENGLISH,
63
+ "Example. `options: { useLegacyDatetimeCode: false, serverTimezone: UTC }`"));
64
+ }
65
+ logger.warn(String.format(Locale.ENGLISH, "The plugin will set `useLegacyDatetimeCode=false` by default in future."));
66
+ }
67
+
68
+ private TimeZone getServerTimeZone()
69
+ throws SQLException
70
+ {
71
+ //
72
+ // First, I used `@@system_time_zone`. but It return non Time Zone Abbreviations name on a specific platform.
73
+ // So, This method calculate GMT offset with query.
74
+ //
75
+ String query = "select TIME_TO_SEC(timediff(now(),utc_timestamp()));";
76
+ Statement stmt = connection.createStatement();
77
+
78
+ try {
79
+ ResultSet rs = stmt.executeQuery(query);
80
+ if (rs.next()) {
81
+ int offsetSeconds = rs.getInt(1);
82
+ return fromGMTOffsetSeconds(offsetSeconds);
83
+ }
84
+ throw new SQLException(String.format(Locale.ENGLISH,
85
+ "The timezone comparison query(%s) doesn't return the result.",query));
86
+ }
87
+ finally {
88
+ stmt.close();
89
+ }
90
+ }
91
+
92
+ private TimeZone fromGMTOffsetSeconds(int offsetSeconds)
93
+ {
94
+ if (offsetSeconds == 0) {
95
+ return TimeZone.getTimeZone("UTC");
96
+ }
97
+
98
+ String sign = offsetSeconds > 0 ? "+" : "-";
99
+ int absOffsetSec = Math.abs(offsetSeconds);
100
+ int tzHour = absOffsetSec / ONE_HOUR_SEC;
101
+ int tzMin = absOffsetSec % ONE_HOUR_SEC / ONE_MIN_SEC;
102
+ String tzName = String.format(Locale.ENGLISH, "GMT%s%02d:%02d", sign, tzHour, tzMin);
103
+ return TimeZone.getTimeZone(tzName);
104
+ }
105
+
106
+
107
+ }
@@ -4,10 +4,12 @@ import java.util.List;
4
4
  import java.sql.Connection;
5
5
  import java.sql.SQLException;
6
6
 
7
+ import org.embulk.output.MySQLTimeZoneComparison;
7
8
  import org.embulk.output.jdbc.JdbcColumn;
8
9
  import org.embulk.output.jdbc.JdbcSchema;
9
10
  import org.embulk.output.jdbc.JdbcOutputConnection;
10
11
  import org.embulk.output.jdbc.MergeConfig;
12
+ import org.embulk.output.jdbc.TableIdentifier;
11
13
 
12
14
  public class MySQLOutputConnection
13
15
  extends JdbcOutputConnection
@@ -20,12 +22,12 @@ public class MySQLOutputConnection
20
22
  }
21
23
 
22
24
  @Override
23
- protected String buildPreparedMergeSql(String toTable, JdbcSchema toTableSchema, MergeConfig mergeConfig) throws SQLException
25
+ protected String buildPreparedMergeSql(TableIdentifier toTable, JdbcSchema toTableSchema, MergeConfig mergeConfig) throws SQLException
24
26
  {
25
27
  StringBuilder sb = new StringBuilder();
26
28
 
27
29
  sb.append("INSERT INTO ");
28
- quoteIdentifierString(sb, toTable);
30
+ quoteTableIdentifier(sb, toTable);
29
31
  sb.append(" (");
30
32
  for (int i = 0; i < toTableSchema.getCount(); i++) {
31
33
  if(i != 0) { sb.append(", "); }
@@ -58,12 +60,12 @@ public class MySQLOutputConnection
58
60
  }
59
61
 
60
62
  @Override
61
- protected String buildCollectMergeSql(List<String> fromTables, JdbcSchema schema, String toTable, MergeConfig mergeConfig) throws SQLException
63
+ protected String buildCollectMergeSql(List<TableIdentifier> fromTables, JdbcSchema schema, TableIdentifier toTable, MergeConfig mergeConfig) throws SQLException
62
64
  {
63
65
  StringBuilder sb = new StringBuilder();
64
66
 
65
67
  sb.append("INSERT INTO ");
66
- quoteIdentifierString(sb, toTable);
68
+ quoteTableIdentifier(sb, toTable);
67
69
  sb.append(" (");
68
70
  for (int i = 0; i < schema.getCount(); i++) {
69
71
  if (i != 0) { sb.append(", "); }
@@ -78,7 +80,7 @@ public class MySQLOutputConnection
78
80
  quoteIdentifierString(sb, schema.getColumnName(j));
79
81
  }
80
82
  sb.append(" FROM ");
81
- quoteIdentifierString(sb, fromTables.get(i));
83
+ quoteTableIdentifier(sb, fromTables.get(i));
82
84
  }
83
85
  sb.append(" ON DUPLICATE KEY UPDATE ");
84
86
  if (mergeConfig.getMergeRule().isPresent()) {
@@ -110,4 +112,11 @@ public class MySQLOutputConnection
110
112
  return super.buildColumnTypeName(c);
111
113
  }
112
114
  }
115
+
116
+ public void compareTimeZone() throws SQLException
117
+ {
118
+ MySQLTimeZoneComparison timeZoneComparison = new MySQLTimeZoneComparison(connection);
119
+ timeZoneComparison.compareTimeZone();
120
+ }
121
+
113
122
  }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: embulk-output-mysql
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.8
4
+ version: 0.7.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sadayuki Furuhashi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-05-10 00:00:00.000000000 Z
11
+ date: 2017-06-23 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Inserts or updates records to a table.
14
14
  email:
@@ -19,11 +19,12 @@ extra_rdoc_files: []
19
19
  files:
20
20
  - README.md
21
21
  - build.gradle
22
- - classpath/embulk-output-jdbc-0.7.8.jar
23
- - classpath/embulk-output-mysql-0.7.8.jar
22
+ - classpath/embulk-output-jdbc-0.7.9.jar
23
+ - classpath/embulk-output-mysql-0.7.9.jar
24
24
  - classpath/mysql-connector-java-5.1.34.jar
25
25
  - lib/embulk/output/mysql.rb
26
26
  - src/main/java/org/embulk/output/MySQLOutputPlugin.java
27
+ - src/main/java/org/embulk/output/MySQLTimeZoneComparison.java
27
28
  - src/main/java/org/embulk/output/mysql/MySQLBatchInsert.java
28
29
  - src/main/java/org/embulk/output/mysql/MySQLOutputConnection.java
29
30
  - src/main/java/org/embulk/output/mysql/MySQLOutputConnector.java