embulk-output-db2 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (30) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +118 -0
  3. data/build.gradle +9 -0
  4. data/classpath/embulk-output-db2-0.7.0.jar +0 -0
  5. data/classpath/embulk-output-jdbc-0.7.0.jar +0 -0
  6. data/lib/embulk/output/db2.rb +3 -0
  7. data/out/test/db2/data/test-char.csv +3 -0
  8. data/out/test/db2/data/test-datetime.csv +3 -0
  9. data/out/test/db2/data/test-number.csv +3 -0
  10. data/out/test/db2/yml/test-insert-direct-char.yml +27 -0
  11. data/out/test/db2/yml/test-insert-direct-datetime.yml +24 -0
  12. data/out/test/db2/yml/test-insert-direct-number.yml +27 -0
  13. data/src/main/java/org/embulk/output/DB2OutputPlugin.java +89 -0
  14. data/src/main/java/org/embulk/output/db2/DB2BatchInsert.java +33 -0
  15. data/src/main/java/org/embulk/output/db2/DB2OutputConnection.java +140 -0
  16. data/src/main/java/org/embulk/output/db2/DB2OutputConnector.java +49 -0
  17. data/src/test/java/org/embulk/output/db2/DB2OutputPluginTest.java +499 -0
  18. data/src/test/resources/db2/data/test-char.csv +3 -0
  19. data/src/test/resources/db2/data/test-datetime.csv +3 -0
  20. data/src/test/resources/db2/data/test-number.csv +3 -0
  21. data/src/test/resources/db2/yml/test-insert-char.yml +27 -0
  22. data/src/test/resources/db2/yml/test-insert-datetime.yml +24 -0
  23. data/src/test/resources/db2/yml/test-insert-direct-char.yml +27 -0
  24. data/src/test/resources/db2/yml/test-insert-direct-datetime.yml +24 -0
  25. data/src/test/resources/db2/yml/test-insert-direct-number.yml +27 -0
  26. data/src/test/resources/db2/yml/test-insert-number.yml +27 -0
  27. data/src/test/resources/db2/yml/test-replace-long-name.yml +27 -0
  28. data/src/test/resources/db2/yml/test-replace.yml +27 -0
  29. data/src/test/resources/db2/yml/test-truncate-insert.yml +27 -0
  30. metadata +72 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b20a23693346957b15458772f8cc1559d4177160
4
+ data.tar.gz: 6476a9a55e25f30e72ce49a12d34aaa3286ce605
5
+ SHA512:
6
+ metadata.gz: fbbd4afe3678831d8f7cd751c81894519a4d677af7e3e82a89f182533d22e7288aa6bec737e45e7637ef0612a85695a34329be15d3538e5312f95230cb208965
7
+ data.tar.gz: 8682f185c18d3a5a5e112c368c7883cfc5bf71d020bf4e781faf51451d2e3cb80ff4a40782403867f2c99fc6088b28bc1b7b44b549dc60d204d3e42f4ae6f9fa
data/README.md ADDED
@@ -0,0 +1,118 @@
1
+ # DB2 output plugins for Embulk
2
+
3
+ DB2 output plugins for Embulk loads records to DB2.
4
+
5
+ ## Overview
6
+
7
+ * **Plugin type**: output
8
+ * **Load all or nothing**: depends on the mode. see below.
9
+ * **Resume supported**: depends on the mode. see below.
10
+
11
+ ## Configuration
12
+
13
+ - **driver_path**: path to the jar file of the DB2 JDBC driver (string)
14
+ - **host**: database host name (string, required)
15
+ - **port**: database port number (integer, default: 50000)
16
+ - **user**: database login user name (string, required)
17
+ - **password**: database login password (string)
18
+ - **database**: destination database name (string, required)
19
+ - **schema**: destination schema name (string, default: use the default schema)
20
+ - **table**: destination table name (string, required)
21
+ - **options**: extra connection properties (hash, default: {})
22
+ - **retry_limit** max retry count for database operations (integer, default: 12)
23
+ - **retry_wait** initial retry wait time in milliseconds (integer, default: 1000 (1 second))
24
+ - **max_retry_wait** upper limit of retry wait, which will be doubled at every retry (integer, default: 1800000 (30 minutes))
25
+ - **mode**: "insert", "insert_direct", "truncate_insert" or "replace". See below. (string, required)
26
+ - **insert_method**: see below
27
+ - **batch_size**: size of a single batch insert (integer, default: 16777216)
28
+ - **default_timezone**: If input column type (embulk type) is timestamp, this plugin needs to format the timestamp into a SQL string. This default_timezone option is used to control the timezone. You can overwrite timezone for each columns using column_options option. (string, default: `UTC`)
29
+ - **column_options**: advanced: a key-value pairs where key is a column name and value is options for the column.
30
+ - **type**: type of a column when this plugin creates new tables (e.g. `VARCHAR(255)`, `INTEGER NOT NULL UNIQUE`). This used when this plugin creates intermediate tables (insert, insert_truncate and merge modes), when it creates the target table (insert_direct, merge_direct and replace modes), and when it creates nonexistent target table automatically. (string, default: depends on input column type. `BIGINT` if input column type is long, `SMALLINT` if boolean, `DOUBLE` if double, `CLOB` if string, `TIMESTAMP` if timestamp)
31
+ - **value_type**: This plugin converts input column type (embulk type) into a database type to build a INSERT statement. This value_type option controls the type of the value in a INSERT statement. (string, default: depends on the sql type of the column. Available values options are: `byte`, `short`, `int`, `long`, `double`, `float`, `boolean`, `string`, `nstring`, `date`, `time`, `timestamp`, `decimal`, `json`, `null`, `pass`)
32
+ - **timestamp_format**: If input column type (embulk type) is timestamp and value_type is `string` or `nstring`, this plugin needs to format the timestamp value into a string. This timestamp_format option is used to control the format of the timestamp. (string, default: `%Y-%m-%d %H:%M:%S.%6N`)
33
+ - **timezone**: If input column type (embulk type) is timestamp, this plugin needs to format the timestamp value into a SQL string. In this cases, this timezone option is used to control the timezone. (string, value of default_timezone option is used by default)
34
+
35
+ ### Modes
36
+
37
+ * **insert**:
38
+ * Behavior: This mode writes rows to some intermediate tables first. If all those tasks run correctly, runs `INSERT INTO <target_table> SELECT * FROM <intermediate_table_1> UNION ALL SELECT * FROM <intermediate_table_2> UNION ALL ...` query. If the target table doesn't exist, it is created automatically.
39
+ * Transactional: Yes. This mode successfully writes all rows, or fails with writing zero rows.
40
+ * Resumable: Yes.
41
+ * **insert_direct**:
42
+ * Behavior: This mode inserts rows to the target table directly. If the target table doesn't exist, it is created automatically.
43
+ * Transactional: No. If fails, the target table could have some rows inserted.
44
+ * Resumable: No.
45
+ * **truncate_insert**:
46
+ * Behavior: Same with `insert` mode excepting that it truncates the target table right before the last `INSERT ...` query.
47
+ * Transactional: Yes.
48
+ * Resumable: Yes.
49
+ * **replace**:
50
+ * Behavior: This mode writes rows to an intermediate table first. If all those tasks run correctly, drops the target table and alters the name of the intermediate table into the target table name.
51
+ * Transactional: No. If fails, the target table could be dropped (because DB2 can't rollback DDL).
52
+ * Resumable: No.
53
+
54
+ ### Supported types
55
+
56
+ |database type|default value_type|note|
57
+ |:--|:--|:--|
58
+ |SMALLINT|short||
59
+ |INTEGER|int||
60
+ |BITINT|long||
61
+ |DECIMAL|decimal||
62
+ |NUMERIC|decimal||
63
+ |REAL|float||
64
+ |DOUBLE|double||
65
+ |FLOAT|double||
66
+ |CHAR|string||
67
+ |VARCHAR|string||
68
+ |CLOB|string||
69
+ |GRAPHIC|string||
70
+ |VARGRAPHIC|string||
71
+ |NCHAR|string||
72
+ |NVARCHAR|string||
73
+ |NCLOB|string||
74
+ |DATE|date||
75
+ |TIME|time||
76
+ |TIMESTAMP|timestamp||
77
+
78
+ You can use other types by specifying `value_type` in `column_options`.
79
+
80
+ ### Example
81
+
82
+ ```yaml
83
+ out:
84
+ type: db2
85
+ driver_path: /opt/db2/db2jcc4.jar
86
+ host: localhost
87
+ user: myuser
88
+ password: ""
89
+ database: my_database
90
+ table: my_table
91
+ mode: insert
92
+ ```
93
+
94
+ Advanced configuration:
95
+
96
+ ```yaml
97
+ out:
98
+ type: db2
99
+ driver_path: /opt/db2/db2jcc4.jar
100
+ host: localhost
101
+ user: myuser
102
+ password: ""
103
+ database: my_database
104
+ table: my_table
105
+ mode: insert_direct
106
+ insert_method: native
107
+ column_options:
108
+ my_col_1: {type: 'TEXT'}
109
+ my_col_3: {type: 'INT NOT NULL'}
110
+ my_col_4: {value_type: string, timestamp_format: `%Y-%m-%d %H:%M:%S %z`, timezone: '-0700'}
111
+ my_col_5: {type: 'DECIMAL(18,9)', value_type: pass}
112
+ ```
113
+
114
+ ### Build
115
+
116
+ ```
117
+ $ ./gradlew gem
118
+ ```
data/build.gradle ADDED
@@ -0,0 +1,9 @@
1
+ [compileTestJava]*.options*.encoding = 'UTF-8'
2
+
3
+ dependencies {
4
+ compile project(':embulk-output-jdbc')
5
+
6
+ testCompile 'org.embulk:embulk-standards:0.8.8'
7
+ testCompile project(':embulk-output-jdbc').sourceSets.test.output
8
+ testCompile files('driver/db2jcc4.jar')
9
+ }
@@ -0,0 +1,3 @@
1
+ Embulk::JavaPlugin.register_output(
2
+ :db2, "org.embulk.output.DB2OutputPlugin",
3
+ File.expand_path('../../../../classpath', __FILE__))
@@ -0,0 +1,3 @@
1
+ A001,aa,AA,aaaaaaaaaaaa,ああ,いいいい,aa,AA,aaaaaaaa
2
+ A002,XXXX,XXXXXXXX,XXXXXXXXXXXXXXXX,XXXX,XXXXXXXX,XXXX,XXXXXXXX,XXXXXXXXXXXXXXXX
3
+ A003,,,,,,,,
@@ -0,0 +1,3 @@
1
+ A001,2016/09/08,12:34:45,2016/09/09 12:34:45.123456,2016/09/10 12:34:45,2016/09/11 12:34:45.123456789012
2
+ A002,2016/12/31,23:59:59,2016/12/31 23:59:59.999999,2016/12/31 23:59:59,2016/12/31 23:59:59.999999999999
3
+ A003,,,,,
@@ -0,0 +1,3 @@
1
+ A001,12345,123456789,123456789012,123456.78,876543.21,1.23456,1.23456789012,3.45678901234
2
+ A002,-9999,-999999999,-999999999999,-999999.99,-999999.99,-9.999999,-9.999999,-9.99999999999999
3
+ A003,,,,,,,,
@@ -0,0 +1,27 @@
1
+ in:
2
+ type: file
3
+ path_prefix: '/db2/data/test-char.csv'
4
+ parser:
5
+ charset: UTF-8
6
+ newline: CRLF
7
+ type: csv
8
+ delimiter: ','
9
+ quote: ''
10
+ columns:
11
+ - {name: ID, type: string}
12
+ - {name: CHAR_ITEM, type: string}
13
+ - {name: VARCHAR_ITEM, type: string}
14
+ - {name: CLOB_ITEM, type: string}
15
+ - {name: GRAPHIC_ITEM, type: string}
16
+ - {name: VARGRAPHIC_ITEM, type: string}
17
+ - {name: NCHAR_ITEM, type: string}
18
+ - {name: NVARCHAR_ITEM, type: string}
19
+ - {name: NCLOB_ITEM, type: string}
20
+ out:
21
+ type: db2
22
+ host: #host#
23
+ database: #database#
24
+ user: #user#
25
+ password: #password#
26
+ table: TEST_CHAR
27
+ mode: insert_direct
@@ -0,0 +1,24 @@
1
+ in:
2
+ type: file
3
+ path_prefix: '/db2/data/test-datetime.csv'
4
+ parser:
5
+ charset: UTF-8
6
+ newline: CRLF
7
+ type: csv
8
+ delimiter: ','
9
+ quote: ''
10
+ columns:
11
+ - {name: ID, type: string}
12
+ - {name: DATE_ITEM, type: timestamp, format: '%Y/%m/%d'}
13
+ - {name: TIME_ITEM, type: timestamp, format: '%H:%M:%S'}
14
+ - {name: TIMESTAMP_ITEM, type: timestamp, format: '%Y/%m/%d %H:%M:%S.%N'}
15
+ - {name: TIMESTAMP0_ITEM, type: timestamp, format: '%Y/%m/%d %H:%M:%S'}
16
+ - {name: TIMESTAMP12_ITEM, type: timestamp, format: '%Y/%m/%d %H:%M:%S.%N'}
17
+ out:
18
+ type: db2
19
+ host: #host#
20
+ database: #database#
21
+ user: #user#
22
+ password: #password#
23
+ table: TEST_DATETIME
24
+ mode: insert_direct
@@ -0,0 +1,27 @@
1
+ in:
2
+ type: file
3
+ path_prefix: '/db2/data/test-number.csv'
4
+ parser:
5
+ charset: UTF-8
6
+ newline: CRLF
7
+ type: csv
8
+ delimiter: ','
9
+ quote: ''
10
+ columns:
11
+ - {name: ID, type: string}
12
+ - {name: SMALLINT_ITEM, type: long}
13
+ - {name: INTEGER_ITEM, type: long}
14
+ - {name: BIGINT_ITEM, type: long}
15
+ - {name: DECIMAL_ITEM, type: string}
16
+ - {name: NUMERIC_ITEM, type: string}
17
+ - {name: REAL_ITEM, type: double}
18
+ - {name: DOUBLE_ITEM, type: double}
19
+ - {name: FLOAT_ITEM, type: double}
20
+ out:
21
+ type: db2
22
+ host: #host#
23
+ database: #database#
24
+ user: #user#
25
+ password: #password#
26
+ table: TEST_NUMBER
27
+ mode: insert_direct
@@ -0,0 +1,89 @@
1
+ package org.embulk.output;
2
+
3
+ import java.io.IOException;
4
+ import java.sql.SQLException;
5
+ import java.util.Properties;
6
+
7
+ import org.embulk.config.Config;
8
+ import org.embulk.config.ConfigDefault;
9
+ import org.embulk.output.db2.DB2BatchInsert;
10
+ import org.embulk.output.db2.DB2OutputConnector;
11
+ import org.embulk.output.jdbc.AbstractJdbcOutputPlugin;
12
+ import org.embulk.output.jdbc.BatchInsert;
13
+ import org.embulk.output.jdbc.MergeConfig;
14
+
15
+ import com.google.common.base.Optional;
16
+ import com.google.common.collect.ImmutableSet;
17
+ import static java.util.Locale.ENGLISH;
18
+
19
+ public class DB2OutputPlugin
20
+ extends AbstractJdbcOutputPlugin
21
+ {
22
+ public interface DB2PluginTask
23
+ extends PluginTask
24
+ {
25
+ @Config("driver_path")
26
+ @ConfigDefault("null")
27
+ public Optional<String> getDriverPath();
28
+
29
+ @Config("host")
30
+ public String getHost();
31
+
32
+ @Config("port")
33
+ @ConfigDefault("50000")
34
+ public int getPort();
35
+
36
+ @Config("database")
37
+ public String getDatabase();
38
+
39
+ @Config("user")
40
+ public String getUser();
41
+
42
+ @Config("password")
43
+ @ConfigDefault("null")
44
+ public Optional<String> getPassword();
45
+ }
46
+
47
+ @Override
48
+ protected Class<? extends PluginTask> getTaskClass()
49
+ {
50
+ return DB2PluginTask.class;
51
+ }
52
+
53
+ @Override
54
+ protected Features getFeatures(PluginTask task)
55
+ {
56
+ return new Features()
57
+ .setMaxTableNameLength(128) // http://www.ibm.com/support/knowledgecenter/SSEPGG_11.1.0/com.ibm.db2.luw.sql.ref.doc/doc/r0001029.html
58
+ .setSupportedModes(ImmutableSet.of(Mode.INSERT, Mode.INSERT_DIRECT, Mode.TRUNCATE_INSERT, Mode.REPLACE))
59
+ .setIgnoreMergeKeys(false);
60
+ }
61
+
62
+ @Override
63
+ protected DB2OutputConnector getConnector(PluginTask task, boolean retryableMetadataOperation)
64
+ {
65
+ DB2PluginTask db2Task = (DB2PluginTask) task;
66
+
67
+ if (db2Task.getDriverPath().isPresent()) {
68
+ loadDriverJar(db2Task.getDriverPath().get());
69
+ }
70
+
71
+ String url = String.format(ENGLISH, "jdbc:db2://%s:%d/%s",
72
+ db2Task.getHost(), db2Task.getPort(), db2Task.getDatabase());
73
+
74
+ Properties props = new Properties();
75
+ props.putAll(db2Task.getOptions());
76
+ props.setProperty("user", db2Task.getUser());
77
+ if (db2Task.getPassword().isPresent()) {
78
+ props.setProperty("password", db2Task.getPassword().get());
79
+ }
80
+
81
+ return new DB2OutputConnector(url, props, null);
82
+ }
83
+
84
+ @Override
85
+ protected BatchInsert newBatchInsert(PluginTask task, Optional<MergeConfig> mergeConfig) throws IOException, SQLException
86
+ {
87
+ return new DB2BatchInsert(getConnector(task, true), mergeConfig);
88
+ }
89
+ }
@@ -0,0 +1,33 @@
1
+ package org.embulk.output.db2;
2
+
3
+ import java.io.IOException;
4
+ import java.sql.SQLException;
5
+
6
+ import org.embulk.output.jdbc.MergeConfig;
7
+ import org.embulk.output.jdbc.StandardBatchInsert;
8
+
9
+ import com.google.common.base.Optional;
10
+
11
+ public class DB2BatchInsert
12
+ extends StandardBatchInsert
13
+ {
14
+ public DB2BatchInsert(DB2OutputConnector connector, Optional<MergeConfig> mergeConfig) throws IOException, SQLException
15
+ {
16
+ super(connector, mergeConfig);
17
+ }
18
+
19
+ @Override
20
+ public void flush() throws IOException, SQLException
21
+ {
22
+ try {
23
+ super.flush();
24
+
25
+ } catch (SQLException e) {
26
+ if (e.getNextException() != null) {
27
+ // SQLException of DB2 doesn't contain details.
28
+ throw new SQLException(e.toString(), e.getNextException());
29
+ }
30
+ throw e;
31
+ }
32
+ }
33
+ }
@@ -0,0 +1,140 @@
1
+ package org.embulk.output.db2;
2
+
3
+ import java.sql.Connection;
4
+ import java.sql.SQLException;
5
+ import java.sql.Statement;
6
+
7
+ import org.embulk.output.jdbc.JdbcColumn;
8
+ import org.embulk.output.jdbc.JdbcOutputConnection;
9
+ import org.embulk.output.jdbc.JdbcSchema;
10
+
11
+ import static java.util.Locale.ENGLISH;
12
+
13
+ public class DB2OutputConnection
14
+ extends JdbcOutputConnection
15
+ {
16
+ public DB2OutputConnection(Connection connection, String schemaName, boolean autoCommit)
17
+ throws SQLException
18
+ {
19
+ super(connection, schemaName);
20
+ connection.setAutoCommit(autoCommit);
21
+ }
22
+
23
+ @Override
24
+ protected String buildRenameTableSql(String fromTable, String toTable)
25
+ {
26
+ StringBuilder sb = new StringBuilder();
27
+ sb.append("RENAME TABLE ");
28
+ sb.append(quoteIdentifierString(fromTable));
29
+ sb.append(" TO ");
30
+ sb.append(quoteIdentifierString(toTable));
31
+ return sb.toString();
32
+ }
33
+
34
+ @Override
35
+ protected void setSearchPath(String schema) throws SQLException
36
+ {
37
+ // NOP
38
+ }
39
+
40
+ @Override
41
+ public void dropTableIfExists(String tableName) throws SQLException
42
+ {
43
+ if (tableExists(tableName)) {
44
+ dropTable(tableName);
45
+ }
46
+ }
47
+
48
+ @Override
49
+ protected void dropTableIfExists(Statement stmt, String tableName) throws SQLException
50
+ {
51
+ if (tableExists(tableName)) {
52
+ dropTable(stmt, tableName);
53
+ }
54
+ }
55
+
56
+ @Override
57
+ public void createTableIfNotExists(String tableName, JdbcSchema schema) throws SQLException
58
+ {
59
+ if (!tableExists(tableName)) {
60
+ createTable(tableName, schema);
61
+ }
62
+ }
63
+
64
+ public void createTable(String tableName, JdbcSchema schema) throws SQLException
65
+ {
66
+ Statement stmt = connection.createStatement();
67
+ try {
68
+ String sql = buildCreateTableSql(tableName, schema);
69
+ executeUpdate(stmt, sql);
70
+ commitIfNecessary(connection);
71
+ } catch (SQLException ex) {
72
+ throw safeRollback(connection, ex);
73
+ } finally {
74
+ stmt.close();
75
+ }
76
+ }
77
+
78
+ protected String buildCreateTableSql(String name, JdbcSchema schema)
79
+ {
80
+ StringBuilder sb = new StringBuilder();
81
+
82
+ sb.append("CREATE TABLE ");
83
+ quoteIdentifierString(sb, name);
84
+ sb.append(buildCreateTableSchemaSql(schema));
85
+ return sb.toString();
86
+ }
87
+
88
+ @Override
89
+ protected String buildColumnTypeName(JdbcColumn c)
90
+ {
91
+ switch(c.getSimpleTypeName()) {
92
+ case "BOOLEAN":
93
+ return "SMALLINT";
94
+
95
+ // NCHAR/NVARCHAR/NCLOB are synonyms for CHAR/VARCHAR/CLOB/GRAPHIC/VARGRAPHIC
96
+ case "CHAR":
97
+ case "VARCHAR":
98
+ case "CLOB":
99
+ String charUnit;
100
+ if (c.getSizeTypeParameter() == c.getDataLength()) {
101
+ charUnit = "OCTETS";
102
+ } else if (c.getSizeTypeParameter() * 2 == c.getDataLength()) {
103
+ charUnit = "CODEUNITS16";
104
+ } else if (c.getSizeTypeParameter() * 4 == c.getDataLength()) {
105
+ charUnit = "CODEUNITS32";
106
+ } else {
107
+ throw new IllegalArgumentException(String.format(ENGLISH, "Column %s has unexpected size %d and length %d.",
108
+ c.getName(), c.getSizeTypeParameter(), c.getDataLength()));
109
+ }
110
+ return String.format(ENGLISH, "%s(%d %s)", c.getSimpleTypeName(), c.getSizeTypeParameter(), charUnit);
111
+
112
+ case "GRAPHIC":
113
+ case "VARGRAPHIC":
114
+ String graphicUnit;
115
+ if (c.getSizeTypeParameter() == c.getDataLength()) {
116
+ graphicUnit = "CODEUNITS16";
117
+ } else if (c.getSizeTypeParameter() * 2 == c.getDataLength()) {
118
+ graphicUnit = "CODEUNITS32";
119
+ } else {
120
+ throw new IllegalArgumentException(String.format(ENGLISH, "Column %s has unexpected size %d and length %d.",
121
+ c.getName(), c.getSizeTypeParameter(), c.getDataLength()));
122
+ }
123
+ return String.format(ENGLISH, "%s(%d %s)", c.getSimpleTypeName(), c.getSizeTypeParameter(), graphicUnit);
124
+
125
+ default:
126
+ return super.buildColumnTypeName(c);
127
+ }
128
+ }
129
+
130
+ @Override
131
+ public void close() throws SQLException
132
+ {
133
+ if (!connection.isClosed()) {
134
+ // DB2 JDBC Driver requires explicit commit/rollback before closing connection.
135
+ connection.rollback();
136
+ }
137
+
138
+ super.close();
139
+ }
140
+ }
@@ -0,0 +1,49 @@
1
+ package org.embulk.output.db2;
2
+
3
+ import java.sql.Connection;
4
+ import java.sql.DriverManager;
5
+ import java.sql.SQLException;
6
+ import java.util.Properties;
7
+
8
+ import org.embulk.output.jdbc.JdbcOutputConnector;
9
+
10
+ public class DB2OutputConnector
11
+ implements JdbcOutputConnector
12
+ {
13
+ private final String url;
14
+ private final Properties properties;
15
+ private final String schemaName;
16
+
17
+ public DB2OutputConnector(String url, Properties properties, String schemaName)
18
+ {
19
+ try {
20
+ Class.forName("com.ibm.db2.jcc.DB2Driver");
21
+ } catch (Exception ex) {
22
+ throw new RuntimeException(ex);
23
+ }
24
+ this.url = url;
25
+ this.properties = properties;
26
+ this.schemaName = schemaName;
27
+ }
28
+
29
+ @Override
30
+ public DB2OutputConnection connect(boolean autoCommit) throws SQLException
31
+ {
32
+ Connection c = DriverManager.getConnection(url, properties);
33
+ if (c == null) {
34
+ // driver.connect returns null when url is "jdbc:mysql://...".
35
+ throw new SQLException("Invalid url : " + url);
36
+ }
37
+
38
+ try {
39
+ DB2OutputConnection con = new DB2OutputConnection(c, schemaName, autoCommit);
40
+ c = null;
41
+ return con;
42
+
43
+ } finally {
44
+ if (c != null) {
45
+ c.close();
46
+ }
47
+ }
48
+ }
49
+ }