embulk-output-jdbc 0.6.1 → 0.6.2
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 +4 -4
- data/classpath/embulk-output-jdbc-0.6.2.jar +0 -0
- data/src/main/java/org/embulk/output/JdbcOutputPlugin.java +3 -8
- data/src/main/java/org/embulk/output/jdbc/AbstractJdbcOutputPlugin.java +156 -86
- data/src/main/java/org/embulk/output/jdbc/JdbcOutputConnection.java +8 -7
- data/src/main/java/org/embulk/output/jdbc/MergeConfig.java +23 -0
- data/src/main/java/org/embulk/output/jdbc/StandardBatchInsert.java +4 -4
- metadata +4 -3
- data/classpath/embulk-output-jdbc-0.6.1.jar +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 050247b8f08b7c7d9c34d2e0c36a4cf9dcfadc18
|
4
|
+
data.tar.gz: 19caf0641d799f247059ac7d5e3247e9895f4a02
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2ea08bdeefad0859f036b475c0e13ea6c803c5d0c14a8ee8368ce912a6d0c743ba16fd460eb9ff6642f3ebb54cbaab798b1c52f757d4da77efd6034a4c5de9e0
|
7
|
+
data.tar.gz: 04c12e62081dc8938a57d7a1e12574235a1fb67eb6042a19408baaa2a6883e7400542a6909761b5d64b219bb214bed056de342409dd3b1bebb5c310ff9efeb9b
|
Binary file
|
@@ -1,6 +1,5 @@
|
|
1
1
|
package org.embulk.output;
|
2
2
|
|
3
|
-
import java.util.List;
|
4
3
|
import java.util.Properties;
|
5
4
|
import java.sql.Driver;
|
6
5
|
import java.io.IOException;
|
@@ -13,11 +12,7 @@ import com.google.common.collect.ImmutableSet;
|
|
13
12
|
|
14
13
|
import org.embulk.config.Config;
|
15
14
|
import org.embulk.config.ConfigDefault;
|
16
|
-
import org.embulk.output.jdbc
|
17
|
-
import org.embulk.output.jdbc.BatchInsert;
|
18
|
-
import org.embulk.output.jdbc.StandardBatchInsert;
|
19
|
-
import org.embulk.output.jdbc.JdbcOutputConnector;
|
20
|
-
import org.embulk.output.jdbc.JdbcOutputConnection;
|
15
|
+
import org.embulk.output.jdbc.*;
|
21
16
|
|
22
17
|
public class JdbcOutputPlugin
|
23
18
|
extends AbstractJdbcOutputPlugin
|
@@ -132,8 +127,8 @@ public class JdbcOutputPlugin
|
|
132
127
|
}
|
133
128
|
|
134
129
|
@Override
|
135
|
-
protected BatchInsert newBatchInsert(PluginTask task, Optional<
|
130
|
+
protected BatchInsert newBatchInsert(PluginTask task, Optional<MergeConfig> mergeConfig) throws IOException, SQLException
|
136
131
|
{
|
137
|
-
return new StandardBatchInsert(getConnector(task, true),
|
132
|
+
return new StandardBatchInsert(getConnector(task, true), mergeConfig);
|
138
133
|
}
|
139
134
|
}
|
@@ -14,6 +14,7 @@ import java.sql.ResultSet;
|
|
14
14
|
import java.sql.DatabaseMetaData;
|
15
15
|
import java.sql.SQLException;
|
16
16
|
|
17
|
+
import org.embulk.spi.util.RetryExecutor;
|
17
18
|
import org.slf4j.Logger;
|
18
19
|
import org.joda.time.DateTimeZone;
|
19
20
|
|
@@ -91,6 +92,22 @@ public abstract class AbstractJdbcOutputPlugin
|
|
91
92
|
@ConfigDefault("\"UTC\"")
|
92
93
|
public DateTimeZone getDefaultTimeZone();
|
93
94
|
|
95
|
+
@Config("retry_limit")
|
96
|
+
@ConfigDefault("12")
|
97
|
+
public int getRetryLimit();
|
98
|
+
|
99
|
+
@Config("retry_wait")
|
100
|
+
@ConfigDefault("1000")
|
101
|
+
public int getRetryWait();
|
102
|
+
|
103
|
+
@Config("max_retry_wait")
|
104
|
+
@ConfigDefault("1800000") // 30 * 60 * 1000
|
105
|
+
public int getMaxRetryWait();
|
106
|
+
|
107
|
+
@Config("merge_rule")
|
108
|
+
@ConfigDefault("null")
|
109
|
+
public Optional<List<String>> getMergeRule();
|
110
|
+
|
94
111
|
public void setActualTable(String actualTable);
|
95
112
|
public String getActualTable();
|
96
113
|
|
@@ -213,7 +230,7 @@ public abstract class AbstractJdbcOutputPlugin
|
|
213
230
|
|
214
231
|
protected abstract JdbcOutputConnector getConnector(PluginTask task, boolean retryableMetadataOperation);
|
215
232
|
|
216
|
-
protected abstract BatchInsert newBatchInsert(PluginTask task, Optional<
|
233
|
+
protected abstract BatchInsert newBatchInsert(PluginTask task, Optional<MergeConfig> mergeConfig) throws IOException, SQLException;
|
217
234
|
|
218
235
|
protected JdbcOutputConnection newConnection(PluginTask task, boolean retryableMetadataOperation,
|
219
236
|
boolean autoCommit) throws SQLException
|
@@ -357,7 +374,7 @@ public abstract class AbstractJdbcOutputPlugin
|
|
357
374
|
final Schema schema, final int taskCount)
|
358
375
|
{
|
359
376
|
try {
|
360
|
-
withRetry(new IdempotentSqlRunnable() { // no intermediate data if isDirectModify == true
|
377
|
+
withRetry(task, new IdempotentSqlRunnable() { // no intermediate data if isDirectModify == true
|
361
378
|
public void run() throws SQLException
|
362
379
|
{
|
363
380
|
JdbcOutputConnection con = newConnection(task, true, false);
|
@@ -379,7 +396,7 @@ public abstract class AbstractJdbcOutputPlugin
|
|
379
396
|
{
|
380
397
|
if (!task.getMode().isDirectModify()) { // no intermediate data if isDirectModify == true
|
381
398
|
try {
|
382
|
-
withRetry(new IdempotentSqlRunnable() {
|
399
|
+
withRetry(task, new IdempotentSqlRunnable() {
|
383
400
|
public void run() throws SQLException
|
384
401
|
{
|
385
402
|
JdbcOutputConnection con = newConnection(task, false, false);
|
@@ -405,7 +422,7 @@ public abstract class AbstractJdbcOutputPlugin
|
|
405
422
|
|
406
423
|
if (!task.getMode().isDirectModify()) { // no intermediate data if isDirectModify == true
|
407
424
|
try {
|
408
|
-
withRetry(new IdempotentSqlRunnable() {
|
425
|
+
withRetry(task, new IdempotentSqlRunnable() {
|
409
426
|
public void run() throws SQLException
|
410
427
|
{
|
411
428
|
JdbcOutputConnection con = newConnection(task, true, true);
|
@@ -682,7 +699,7 @@ public abstract class AbstractJdbcOutputPlugin
|
|
682
699
|
if (task.getNewTableSchema().isPresent()) {
|
683
700
|
con.createTableIfNotExists(task.getActualTable(), task.getNewTableSchema().get());
|
684
701
|
}
|
685
|
-
con.collectMerge(task.getIntermediateTables().get(), schema, task.getActualTable(), task.getMergeKeys().get());
|
702
|
+
con.collectMerge(task.getIntermediateTables().get(), schema, task.getActualTable(), new MergeConfig(task.getMergeKeys().get(), task.getMergeRule()));
|
686
703
|
break;
|
687
704
|
|
688
705
|
case REPLACE:
|
@@ -829,10 +846,11 @@ public abstract class AbstractJdbcOutputPlugin
|
|
829
846
|
// instantiate BatchInsert without table name
|
830
847
|
BatchInsert batch = null;
|
831
848
|
try {
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
849
|
+
Optional<MergeConfig> config = Optional.absent();
|
850
|
+
if (task.getMode() == Mode.MERGE_DIRECT) {
|
851
|
+
config = Optional.of(new MergeConfig(task.getMergeKeys().get(), task.getMergeRule()));
|
852
|
+
}
|
853
|
+
batch = newBatchInsert(task, config);
|
836
854
|
} catch (IOException | SQLException ex) {
|
837
855
|
throw new RuntimeException(ex);
|
838
856
|
}
|
@@ -861,7 +879,7 @@ public abstract class AbstractJdbcOutputPlugin
|
|
861
879
|
}
|
862
880
|
batch.prepare(destTable, insertIntoSchema);
|
863
881
|
|
864
|
-
PluginPageOutput output = new PluginPageOutput(reader, batch, columnSetters, task.getBatchSize());
|
882
|
+
PluginPageOutput output = new PluginPageOutput(reader, batch, columnSetters, task.getBatchSize(), task);
|
865
883
|
batch = null;
|
866
884
|
return output;
|
867
885
|
|
@@ -879,7 +897,7 @@ public abstract class AbstractJdbcOutputPlugin
|
|
879
897
|
}
|
880
898
|
}
|
881
899
|
|
882
|
-
public
|
900
|
+
public class PluginPageOutput
|
883
901
|
implements TransactionalPageOutput
|
884
902
|
{
|
885
903
|
protected final List<Column> columns;
|
@@ -888,10 +906,11 @@ public abstract class AbstractJdbcOutputPlugin
|
|
888
906
|
private final BatchInsert batch;
|
889
907
|
private final int batchSize;
|
890
908
|
private final int forceBatchFlushSize;
|
909
|
+
private final PluginTask task;
|
891
910
|
|
892
911
|
public PluginPageOutput(final PageReader pageReader,
|
893
912
|
BatchInsert batch, List<ColumnSetter> columnSetters,
|
894
|
-
int batchSize)
|
913
|
+
int batchSize, PluginTask task)
|
895
914
|
{
|
896
915
|
this.pageReader = pageReader;
|
897
916
|
this.batch = batch;
|
@@ -904,6 +923,7 @@ public abstract class AbstractJdbcOutputPlugin
|
|
904
923
|
}
|
905
924
|
}));
|
906
925
|
this.batchSize = batchSize;
|
926
|
+
this.task = task;
|
907
927
|
this.forceBatchFlushSize = batchSize * 2;
|
908
928
|
}
|
909
929
|
|
@@ -914,15 +934,33 @@ public abstract class AbstractJdbcOutputPlugin
|
|
914
934
|
pageReader.setPage(page);
|
915
935
|
while (pageReader.nextRecord()) {
|
916
936
|
if (batch.getBatchWeight() > forceBatchFlushSize) {
|
917
|
-
|
937
|
+
withRetry(task, new IdempotentSqlRunnable() {
|
938
|
+
@Override
|
939
|
+
public void run() throws SQLException {
|
940
|
+
try {
|
941
|
+
batch.flush();
|
942
|
+
} catch (IOException ex) {
|
943
|
+
throw new RuntimeException(ex);
|
944
|
+
}
|
945
|
+
}
|
946
|
+
});
|
918
947
|
}
|
919
948
|
handleColumnsSetters();
|
920
949
|
batch.add();
|
921
950
|
}
|
922
951
|
if (batch.getBatchWeight() > batchSize) {
|
923
|
-
|
952
|
+
withRetry(task, new IdempotentSqlRunnable() {
|
953
|
+
@Override
|
954
|
+
public void run() throws SQLException {
|
955
|
+
try {
|
956
|
+
batch.flush();
|
957
|
+
} catch (IOException ex) {
|
958
|
+
throw new RuntimeException(ex);
|
959
|
+
}
|
960
|
+
}
|
961
|
+
});
|
924
962
|
}
|
925
|
-
} catch (IOException | SQLException ex) {
|
963
|
+
} catch (IOException | SQLException | InterruptedException ex) {
|
926
964
|
throw new RuntimeException(ex);
|
927
965
|
}
|
928
966
|
}
|
@@ -931,8 +969,17 @@ public abstract class AbstractJdbcOutputPlugin
|
|
931
969
|
public void finish()
|
932
970
|
{
|
933
971
|
try {
|
934
|
-
|
935
|
-
|
972
|
+
withRetry(task, new IdempotentSqlRunnable() {
|
973
|
+
@Override
|
974
|
+
public void run() throws SQLException {
|
975
|
+
try {
|
976
|
+
batch.finish();
|
977
|
+
} catch (IOException ex) {
|
978
|
+
throw new RuntimeException(ex);
|
979
|
+
}
|
980
|
+
}
|
981
|
+
});
|
982
|
+
} catch (InterruptedException | SQLException ex) {
|
936
983
|
throw new RuntimeException(ex);
|
937
984
|
}
|
938
985
|
}
|
@@ -967,73 +1014,33 @@ public abstract class AbstractJdbcOutputPlugin
|
|
967
1014
|
}
|
968
1015
|
}
|
969
1016
|
|
1017
|
+
protected boolean isRetryableException(SQLException exception)
|
1018
|
+
{
|
1019
|
+
return isRetryableException(exception.getSQLState(), exception.getErrorCode());
|
1020
|
+
}
|
1021
|
+
protected boolean isRetryableException(String sqlState, int errorCode)
|
1022
|
+
{
|
1023
|
+
return false;
|
1024
|
+
}
|
1025
|
+
|
1026
|
+
|
970
1027
|
public static interface IdempotentSqlRunnable
|
971
1028
|
{
|
972
1029
|
public void run() throws SQLException;
|
973
1030
|
}
|
974
1031
|
|
975
|
-
protected void withRetry(IdempotentSqlRunnable op)
|
1032
|
+
protected void withRetry(PluginTask task, IdempotentSqlRunnable op)
|
976
1033
|
throws SQLException, InterruptedException
|
977
1034
|
{
|
978
|
-
withRetry(op, "Operation failed");
|
1035
|
+
withRetry(task, op, "Operation failed");
|
979
1036
|
}
|
980
1037
|
|
981
|
-
protected void withRetry(final IdempotentSqlRunnable op, final String errorMessage)
|
1038
|
+
protected void withRetry(PluginTask task, final IdempotentSqlRunnable op, final String errorMessage)
|
982
1039
|
throws SQLException, InterruptedException
|
983
1040
|
{
|
984
1041
|
try {
|
985
|
-
|
986
|
-
.
|
987
|
-
.withInitialRetryWait(1000)
|
988
|
-
.withMaxRetryWait(30 * 60 * 1000)
|
989
|
-
.runInterruptible(new Retryable<Void>() {
|
990
|
-
public Void call() throws Exception
|
991
|
-
{
|
992
|
-
op.run();
|
993
|
-
return null;
|
994
|
-
}
|
995
|
-
|
996
|
-
public void onRetry(Exception exception, int retryCount, int retryLimit, int retryWait)
|
997
|
-
{
|
998
|
-
if (exception instanceof SQLException) {
|
999
|
-
SQLException ex = (SQLException) exception;
|
1000
|
-
String sqlState = ex.getSQLState();
|
1001
|
-
int errorCode = ex.getErrorCode();
|
1002
|
-
logger.warn("{} ({}:{}), retrying {}/{} after {} seconds. Message: {}",
|
1003
|
-
errorMessage, errorCode, sqlState, retryCount, retryLimit, retryWait/1000,
|
1004
|
-
buildExceptionMessage(exception));
|
1005
|
-
} else {
|
1006
|
-
logger.warn("{}, retrying {}/{} after {} seconds. Message: {}",
|
1007
|
-
errorMessage, retryCount, retryLimit, retryWait/1000,
|
1008
|
-
buildExceptionMessage(exception));
|
1009
|
-
}
|
1010
|
-
if (retryCount % 3 == 0) {
|
1011
|
-
logger.info("Error details:", exception);
|
1012
|
-
}
|
1013
|
-
}
|
1014
|
-
|
1015
|
-
public void onGiveup(Exception firstException, Exception lastException)
|
1016
|
-
{
|
1017
|
-
if (firstException instanceof SQLException) {
|
1018
|
-
SQLException ex = (SQLException) firstException;
|
1019
|
-
String sqlState = ex.getSQLState();
|
1020
|
-
int errorCode = ex.getErrorCode();
|
1021
|
-
logger.error("{} ({}:{})", errorMessage, errorCode, sqlState);
|
1022
|
-
}
|
1023
|
-
}
|
1024
|
-
|
1025
|
-
public boolean isRetryableException(Exception exception)
|
1026
|
-
{
|
1027
|
-
//if (exception instanceof SQLException) {
|
1028
|
-
// SQLException ex = (SQLException) exception;
|
1029
|
-
// String sqlState = ex.getSQLState();
|
1030
|
-
// int errorCode = ex.getErrorCode();
|
1031
|
-
// return isRetryableSQLException(ex);
|
1032
|
-
//}
|
1033
|
-
return false; // TODO
|
1034
|
-
}
|
1035
|
-
});
|
1036
|
-
|
1042
|
+
buildRetryExecutor(task)
|
1043
|
+
.runInterruptible(new RetryableSQLExecution(op, errorMessage));
|
1037
1044
|
} catch (ExecutionException ex) {
|
1038
1045
|
Throwable cause = ex.getCause();
|
1039
1046
|
Throwables.propagateIfInstanceOf(cause, SQLException.class);
|
@@ -1041,24 +1048,87 @@ public abstract class AbstractJdbcOutputPlugin
|
|
1041
1048
|
}
|
1042
1049
|
}
|
1043
1050
|
|
1044
|
-
private
|
1045
|
-
|
1046
|
-
|
1047
|
-
|
1048
|
-
|
1049
|
-
}
|
1050
|
-
return sb.toString();
|
1051
|
+
private static RetryExecutor buildRetryExecutor(PluginTask task) {
|
1052
|
+
return retryExecutor()
|
1053
|
+
.withRetryLimit(task.getRetryLimit())
|
1054
|
+
.withInitialRetryWait(task.getRetryWait())
|
1055
|
+
.withMaxRetryWait(task.getMaxRetryWait());
|
1051
1056
|
}
|
1052
1057
|
|
1053
|
-
|
1054
|
-
|
1055
|
-
|
1056
|
-
|
1058
|
+
class RetryableSQLExecution implements Retryable<Void> {
|
1059
|
+
private final String errorMessage;
|
1060
|
+
private final IdempotentSqlRunnable op;
|
1061
|
+
|
1062
|
+
private final Logger logger = Exec.getLogger(this.getClass());
|
1063
|
+
|
1064
|
+
public RetryableSQLExecution(IdempotentSqlRunnable op, String errorMessage) {
|
1065
|
+
this.errorMessage = errorMessage;
|
1066
|
+
this.op = op;
|
1067
|
+
}
|
1068
|
+
|
1069
|
+
public Void call() throws Exception {
|
1070
|
+
op.run();
|
1071
|
+
return null;
|
1072
|
+
}
|
1073
|
+
|
1074
|
+
public void onRetry(Exception exception, int retryCount, int retryLimit, int retryWait)
|
1075
|
+
{
|
1076
|
+
if (exception instanceof SQLException) {
|
1077
|
+
SQLException ex = (SQLException) exception;
|
1078
|
+
String sqlState = ex.getSQLState();
|
1079
|
+
int errorCode = ex.getErrorCode();
|
1080
|
+
logger.warn("{} ({}:{}), retrying {}/{} after {} seconds. Message: {}",
|
1081
|
+
errorMessage, errorCode, sqlState, retryCount, retryLimit, retryWait/1000,
|
1082
|
+
buildExceptionMessage(exception));
|
1083
|
+
} else {
|
1084
|
+
logger.warn("{}, retrying {}/{} after {} seconds. Message: {}",
|
1085
|
+
errorMessage, retryCount, retryLimit, retryWait/1000,
|
1086
|
+
buildExceptionMessage(exception));
|
1087
|
+
}
|
1088
|
+
if (retryCount % 3 == 0) {
|
1089
|
+
logger.info("Error details:", exception);
|
1090
|
+
}
|
1091
|
+
}
|
1092
|
+
|
1093
|
+
public void onGiveup(Exception firstException, Exception lastException)
|
1094
|
+
{
|
1095
|
+
if (firstException instanceof SQLException) {
|
1096
|
+
SQLException ex = (SQLException) firstException;
|
1097
|
+
String sqlState = ex.getSQLState();
|
1098
|
+
int errorCode = ex.getErrorCode();
|
1099
|
+
logger.error("{} ({}:{})", errorMessage, errorCode, sqlState);
|
1100
|
+
}
|
1101
|
+
}
|
1102
|
+
|
1103
|
+
public boolean isRetryableException(Exception exception) {
|
1104
|
+
if (exception instanceof SQLException) {
|
1105
|
+
SQLException ex = (SQLException)exception;
|
1106
|
+
|
1107
|
+
return AbstractJdbcOutputPlugin.this.isRetryableException(ex);
|
1108
|
+
} else {
|
1109
|
+
return false;
|
1110
|
+
}
|
1111
|
+
}
|
1112
|
+
|
1113
|
+
private String buildExceptionMessage(Throwable ex) {
|
1114
|
+
StringBuilder sb = new StringBuilder();
|
1057
1115
|
sb.append(ex.getMessage());
|
1116
|
+
if (ex.getCause() != null) {
|
1117
|
+
buildExceptionMessageCont(sb, ex.getCause(), ex.getMessage());
|
1118
|
+
}
|
1119
|
+
return sb.toString();
|
1058
1120
|
}
|
1059
|
-
|
1060
|
-
|
1121
|
+
|
1122
|
+
private void buildExceptionMessageCont(StringBuilder sb, Throwable ex, String lastMessage) {
|
1123
|
+
if (!lastMessage.equals(ex.getMessage())) {
|
1124
|
+
// suppress same messages
|
1125
|
+
sb.append(" < ");
|
1126
|
+
sb.append(ex.getMessage());
|
1127
|
+
}
|
1128
|
+
if (ex.getCause() == null) {
|
1129
|
+
return;
|
1130
|
+
}
|
1131
|
+
buildExceptionMessageCont(sb, ex.getCause(), ex.getMessage());
|
1061
1132
|
}
|
1062
|
-
buildExceptionMessageCont(sb, ex.getCause(), ex.getMessage());
|
1063
1133
|
}
|
1064
1134
|
}
|
@@ -9,6 +9,7 @@ import java.sql.PreparedStatement;
|
|
9
9
|
import java.sql.ResultSet;
|
10
10
|
import java.sql.SQLException;
|
11
11
|
import java.sql.Statement;
|
12
|
+
|
12
13
|
import org.slf4j.Logger;
|
13
14
|
import com.google.common.base.Optional;
|
14
15
|
import org.embulk.spi.Exec;
|
@@ -240,11 +241,11 @@ public class JdbcOutputConnection
|
|
240
241
|
return ColumnDeclareType.SIMPLE;
|
241
242
|
}
|
242
243
|
|
243
|
-
public PreparedStatement prepareBatchInsertStatement(String toTable, JdbcSchema toTableSchema, Optional<
|
244
|
+
public PreparedStatement prepareBatchInsertStatement(String toTable, JdbcSchema toTableSchema, Optional<MergeConfig> mergeConfig) throws SQLException
|
244
245
|
{
|
245
246
|
String sql;
|
246
|
-
if (
|
247
|
-
sql = buildPreparedMergeSql(toTable, toTableSchema,
|
247
|
+
if (mergeConfig.isPresent()) {
|
248
|
+
sql = buildPreparedMergeSql(toTable, toTableSchema, mergeConfig.get());
|
248
249
|
} else {
|
249
250
|
sql = buildPreparedInsertSql(toTable, toTableSchema);
|
250
251
|
}
|
@@ -274,7 +275,7 @@ public class JdbcOutputConnection
|
|
274
275
|
return sb.toString();
|
275
276
|
}
|
276
277
|
|
277
|
-
protected String buildPreparedMergeSql(String toTable, JdbcSchema toTableSchema,
|
278
|
+
protected String buildPreparedMergeSql(String toTable, JdbcSchema toTableSchema, MergeConfig mergeConfig) throws SQLException
|
278
279
|
{
|
279
280
|
throw new UnsupportedOperationException("not implemented");
|
280
281
|
}
|
@@ -334,11 +335,11 @@ public class JdbcOutputConnection
|
|
334
335
|
return sb.toString();
|
335
336
|
}
|
336
337
|
|
337
|
-
protected void collectMerge(List<String> fromTables, JdbcSchema schema, String toTable,
|
338
|
+
protected void collectMerge(List<String> fromTables, JdbcSchema schema, String toTable, MergeConfig mergeConfig) throws SQLException
|
338
339
|
{
|
339
340
|
Statement stmt = connection.createStatement();
|
340
341
|
try {
|
341
|
-
String sql = buildCollectMergeSql(fromTables, schema, toTable,
|
342
|
+
String sql = buildCollectMergeSql(fromTables, schema, toTable, mergeConfig);
|
342
343
|
executeUpdate(stmt, sql);
|
343
344
|
commitIfNecessary(connection);
|
344
345
|
} catch (SQLException ex) {
|
@@ -348,7 +349,7 @@ public class JdbcOutputConnection
|
|
348
349
|
}
|
349
350
|
}
|
350
351
|
|
351
|
-
protected String buildCollectMergeSql(List<String> fromTables, JdbcSchema schema, String toTable,
|
352
|
+
protected String buildCollectMergeSql(List<String> fromTables, JdbcSchema schema, String toTable, MergeConfig mergeConfig) throws SQLException
|
352
353
|
{
|
353
354
|
throw new UnsupportedOperationException("not implemented");
|
354
355
|
}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
package org.embulk.output.jdbc;
|
2
|
+
|
3
|
+
import com.google.common.base.Optional;
|
4
|
+
|
5
|
+
import java.util.List;
|
6
|
+
|
7
|
+
public class MergeConfig {
|
8
|
+
private final List<String> mergeKeys;
|
9
|
+
private final Optional<List<String>> mergeRule;
|
10
|
+
|
11
|
+
public MergeConfig(List<String> mergeKeys, Optional<List<String>> mergeRule) {
|
12
|
+
this.mergeKeys = mergeKeys;
|
13
|
+
this.mergeRule = mergeRule;
|
14
|
+
}
|
15
|
+
|
16
|
+
public List<String> getMergeKeys() {
|
17
|
+
return mergeKeys;
|
18
|
+
}
|
19
|
+
|
20
|
+
public Optional<List<String>> getMergeRule() {
|
21
|
+
return mergeRule;
|
22
|
+
}
|
23
|
+
}
|
@@ -19,7 +19,7 @@ public class StandardBatchInsert
|
|
19
19
|
private final Logger logger = Exec.getLogger(StandardBatchInsert.class);
|
20
20
|
|
21
21
|
private final JdbcOutputConnector connector;
|
22
|
-
private final Optional<
|
22
|
+
private final Optional<MergeConfig> mergeConfig;
|
23
23
|
|
24
24
|
private JdbcOutputConnection connection;
|
25
25
|
private PreparedStatement batch;
|
@@ -28,10 +28,10 @@ public class StandardBatchInsert
|
|
28
28
|
private int batchRows;
|
29
29
|
private long totalRows;
|
30
30
|
|
31
|
-
public StandardBatchInsert(JdbcOutputConnector connector, Optional<
|
31
|
+
public StandardBatchInsert(JdbcOutputConnector connector, Optional<MergeConfig> mergeConfig) throws IOException, SQLException
|
32
32
|
{
|
33
33
|
this.connector = connector;
|
34
|
-
this.
|
34
|
+
this.mergeConfig = mergeConfig;
|
35
35
|
}
|
36
36
|
|
37
37
|
public void prepare(String loadTable, JdbcSchema insertSchema) throws SQLException
|
@@ -46,7 +46,7 @@ public class StandardBatchInsert
|
|
46
46
|
|
47
47
|
protected PreparedStatement prepareStatement(String loadTable, JdbcSchema insertSchema) throws SQLException
|
48
48
|
{
|
49
|
-
return connection.prepareBatchInsertStatement(loadTable, insertSchema,
|
49
|
+
return connection.prepareBatchInsertStatement(loadTable, insertSchema, mergeConfig);
|
50
50
|
}
|
51
51
|
|
52
52
|
public int getBatchWeight()
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: embulk-output-jdbc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sadayuki Furuhashi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-08-10 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Inserts or updates records to a table.
|
14
14
|
email:
|
@@ -28,6 +28,7 @@ files:
|
|
28
28
|
- src/main/java/org/embulk/output/jdbc/JdbcOutputConnector.java
|
29
29
|
- src/main/java/org/embulk/output/jdbc/JdbcSchema.java
|
30
30
|
- src/main/java/org/embulk/output/jdbc/JdbcUtils.java
|
31
|
+
- src/main/java/org/embulk/output/jdbc/MergeConfig.java
|
31
32
|
- src/main/java/org/embulk/output/jdbc/StandardBatchInsert.java
|
32
33
|
- src/main/java/org/embulk/output/jdbc/TimestampFormat.java
|
33
34
|
- src/main/java/org/embulk/output/jdbc/ToString.java
|
@@ -58,7 +59,7 @@ files:
|
|
58
59
|
- src/test/java/org/embulk/output/TestJdbcOutputPlugin.java
|
59
60
|
- src/test/java/org/embulk/output/TimestampFormatTest.java
|
60
61
|
- src/test/java/org/embulk/output/tester/EmbulkPluginTester.java
|
61
|
-
- classpath/embulk-output-jdbc-0.6.
|
62
|
+
- classpath/embulk-output-jdbc-0.6.2.jar
|
62
63
|
homepage: https://github.com/embulk/embulk-output-jdbc
|
63
64
|
licenses:
|
64
65
|
- Apache 2.0
|
Binary file
|