embulk-output-mysql 0.7.8 → 0.7.9

Sign up to get free protection for your applications and to get access to all the features.
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