embulk-output-jdbc 0.6.1 → 0.6.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|