embulk-output-jdbc 0.8.2 → 0.8.3

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: d3891c0b994ce34234e7b90ded03dacf56fc9f66
4
- data.tar.gz: 3cda1683bbdad0cab85467765be2a0c16c03b31d
3
+ metadata.gz: 1c01d9d1c8f2babb4d908929c0118a5a9c28d87f
4
+ data.tar.gz: c16e74184b0f5a59b8cac366bcfca99e5a38cb1c
5
5
  SHA512:
6
- metadata.gz: e6f380f77d762d8cf2f26a370ab883637a1179831d099b492374b297a0e95f52947faf0ce010fdf6073f9a2b71eefee73f3b7153ed6e4a23de04dad67d2dd0b8
7
- data.tar.gz: b5f508e16456ad41f61c192d6ee0a5790685c116c2a4803cea7abb8a575981113fb8341af47906fe49d0044e9a300dcfe9aab8f9297eb29b8abe7d61ad20c447
6
+ metadata.gz: 5a3b33623d041ced79d8c4cb885ddbe8505da46395cb1953523874e58b4eb8a630eed4e9ca8a6c16eb4051bc44dd2c973dbb6cad3f6023daebddf8892eabaffa
7
+ data.tar.gz: 3df9712d68feca663e6bcbf053c8856ee2dc8779a80515da63457040a7bf0261d1a018e50eac461d10dd0fe4ba408c8e20bd58a4bfefbc6d076f7926f187d79f
data/README.md CHANGED
@@ -19,8 +19,9 @@ Generic JDBC output plugin for Embulk loads records to a database using a JDBC d
19
19
  - **table**: destination table name (string, required)
20
20
  - **create_table_constraint**: table constraint added to `CREATE TABLE` statement, like `CREATE TABLE <table_name> (<column1> <type1>, <column2> <type2>, ..., <create_table_constraint>) <create_table_option>`.
21
21
  - **create_table_option**: table option added to `CREATE TABLE` statement, like `CREATE TABLE <table_name> (<column1> <type1>, <column2> <type2>, ..., <create_table_constraint>) <create_table_option>`.
22
+ - **transaction_isolation**: transaction isolation level for each connection ("read_uncommitted", "read_committed", "repeatable_read" or "serializable"). if not specified, database default value will be used.
22
23
  - **options**: extra JDBC properties (hash, default: {})
23
- - **retry_limit**: max retry count for database operations (integer, default: 12)
24
+ - **retry_limit**: max retry count for database operations (integer, default: 12). When intermediate table to create already created by another process, this plugin will retry with another table name to avoid collision.
24
25
  - **retry_wait**: initial retry wait time in milliseconds (integer, default: 1000 (1 second))
25
26
  - **max_retry_wait**: upper limit of retry wait, which will be doubled at every retry (integer, default: 1800000 (30 minutes))
26
27
  - **mode**: "insert", "insert_direct", "truncate_insert", or "replace". See below (string, required)
@@ -0,0 +1,24 @@
1
+ package org.embulk.output.jdbc;
2
+
3
+ import java.sql.SQLException;
4
+
5
+ import com.google.common.base.Optional;
6
+
7
+ public abstract class AbstractJdbcOutputConnector implements JdbcOutputConnector
8
+ {
9
+ private final Optional<TransactionIsolation> transactionIsolation;
10
+
11
+ public AbstractJdbcOutputConnector(Optional<TransactionIsolation> transactionIsolation)
12
+ {
13
+ this.transactionIsolation = transactionIsolation;
14
+ }
15
+
16
+ public JdbcOutputConnection connect(boolean autoCommit) throws SQLException
17
+ {
18
+ JdbcOutputConnection connection = connect();
19
+ connection.initialize(autoCommit, transactionIsolation);
20
+ return connection;
21
+ }
22
+
23
+ protected abstract JdbcOutputConnection connect() throws SQLException;
24
+ }
@@ -128,6 +128,11 @@ public abstract class AbstractJdbcOutputPlugin
128
128
  @ConfigDefault("null")
129
129
  public Optional<String> getAfterLoad();
130
130
 
131
+ @Config("transaction_isolation")
132
+ @ConfigDefault("null")
133
+ public Optional<TransactionIsolation> getTransactionIsolation();
134
+ public void setTransactionIsolation(Optional<TransactionIsolation> transactionIsolation);
135
+
131
136
  public void setActualTable(TableIdentifier actualTable);
132
137
  public TableIdentifier getActualTable();
133
138
 
@@ -1070,25 +1075,27 @@ public abstract class AbstractJdbcOutputPlugin
1070
1075
  implements TransactionalPageOutput
1071
1076
  {
1072
1077
  protected final List<Column> columns;
1078
+ protected final List<ColumnSetter> columnSetters;
1073
1079
  protected final List<ColumnSetterVisitor> columnVisitors;
1074
- private final PageReader pageReader;
1080
+ private final PageReaderRecord pageReader;
1075
1081
  private final BatchInsert batch;
1076
1082
  private final int batchSize;
1077
1083
  private final int forceBatchFlushSize;
1078
1084
  private final PluginTask task;
1079
1085
 
1080
- public PluginPageOutput(final PageReader pageReader,
1086
+ public PluginPageOutput(PageReader pageReader,
1081
1087
  BatchInsert batch, List<ColumnSetter> columnSetters,
1082
1088
  int batchSize, PluginTask task)
1083
1089
  {
1084
- this.pageReader = pageReader;
1090
+ this.pageReader = new PageReaderRecord(pageReader);
1085
1091
  this.batch = batch;
1086
1092
  this.columns = pageReader.getSchema().getColumns();
1093
+ this.columnSetters = columnSetters;
1087
1094
  this.columnVisitors = ImmutableList.copyOf(Lists.transform(
1088
1095
  columnSetters, new Function<ColumnSetter, ColumnSetterVisitor>() {
1089
1096
  public ColumnSetterVisitor apply(ColumnSetter setter)
1090
1097
  {
1091
- return new ColumnSetterVisitor(pageReader, setter);
1098
+ return new ColumnSetterVisitor(PluginPageOutput.this.pageReader, setter);
1092
1099
  }
1093
1100
  }));
1094
1101
  this.batchSize = batchSize;
@@ -1103,49 +1110,57 @@ public abstract class AbstractJdbcOutputPlugin
1103
1110
  pageReader.setPage(page);
1104
1111
  while (pageReader.nextRecord()) {
1105
1112
  if (batch.getBatchWeight() > forceBatchFlushSize) {
1106
- withRetry(task, new IdempotentSqlRunnable() {
1107
- @Override
1108
- public void run() throws SQLException {
1109
- try {
1110
- batch.flush();
1111
- } catch (IOException ex) {
1112
- throw new RuntimeException(ex);
1113
- }
1114
- }
1115
- });
1113
+ flush();
1116
1114
  }
1117
1115
  handleColumnsSetters();
1118
1116
  batch.add();
1119
1117
  }
1120
1118
  if (batch.getBatchWeight() > batchSize) {
1121
- withRetry(task, new IdempotentSqlRunnable() {
1122
- @Override
1123
- public void run() throws SQLException {
1124
- try {
1125
- batch.flush();
1126
- } catch (IOException ex) {
1127
- throw new RuntimeException(ex);
1128
- }
1129
- }
1130
- });
1119
+ flush();
1131
1120
  }
1132
1121
  } catch (IOException | SQLException | InterruptedException ex) {
1133
1122
  throw new RuntimeException(ex);
1134
1123
  }
1135
1124
  }
1136
1125
 
1126
+ private void flush() throws SQLException, InterruptedException
1127
+ {
1128
+ withRetry(task, new IdempotentSqlRunnable() {
1129
+ private boolean first = true;
1130
+
1131
+ @Override
1132
+ public void run() throws IOException, SQLException {
1133
+ try {
1134
+ if (!first) {
1135
+ retryColumnsSetters();
1136
+ }
1137
+
1138
+ batch.flush();
1139
+
1140
+ } catch (IOException | SQLException ex) {
1141
+ if (!first && !isRetryableException(ex)) {
1142
+ logger.error("Retry failed : ", ex);
1143
+ }
1144
+ throw ex;
1145
+ } finally {
1146
+ first = false;
1147
+ }
1148
+ }
1149
+ });
1150
+
1151
+ pageReader.clearReadRecords();
1152
+ }
1153
+
1137
1154
  @Override
1138
1155
  public void finish()
1139
1156
  {
1140
1157
  try {
1158
+ flush();
1159
+
1141
1160
  withRetry(task, new IdempotentSqlRunnable() {
1142
1161
  @Override
1143
- public void run() throws SQLException {
1144
- try {
1145
- batch.finish();
1146
- } catch (IOException ex) {
1147
- throw new RuntimeException(ex);
1148
- }
1162
+ public void run() throws IOException, SQLException {
1163
+ batch.finish();
1149
1164
  }
1150
1165
  });
1151
1166
  } catch (InterruptedException | SQLException ex) {
@@ -1181,12 +1196,30 @@ public abstract class AbstractJdbcOutputPlugin
1181
1196
  columns.get(i).visit(columnVisitors.get(i));
1182
1197
  }
1183
1198
  }
1199
+
1200
+ protected void retryColumnsSetters() throws IOException, SQLException
1201
+ {
1202
+ int size = columnVisitors.size();
1203
+ for (Record record : pageReader.getReadRecords()) {
1204
+ for (int i = 0; i < size; i++) {
1205
+ ColumnSetterVisitor columnVisitor = new ColumnSetterVisitor(record, columnSetters.get(i));
1206
+ columns.get(i).visit(columnVisitor);
1207
+ }
1208
+ batch.add();
1209
+ }
1210
+ }
1184
1211
  }
1185
1212
 
1186
- protected boolean isRetryableException(SQLException exception)
1213
+ protected boolean isRetryableException(Exception exception)
1187
1214
  {
1188
- return isRetryableException(exception.getSQLState(), exception.getErrorCode());
1215
+ if (exception instanceof SQLException) {
1216
+ SQLException ex = (SQLException)exception;
1217
+ return isRetryableException(ex.getSQLState(), ex.getErrorCode());
1218
+ } else {
1219
+ return false;
1220
+ }
1189
1221
  }
1222
+
1190
1223
  protected boolean isRetryableException(String sqlState, int errorCode)
1191
1224
  {
1192
1225
  return false;
@@ -1195,7 +1228,7 @@ public abstract class AbstractJdbcOutputPlugin
1195
1228
 
1196
1229
  public static interface IdempotentSqlRunnable
1197
1230
  {
1198
- public void run() throws SQLException;
1231
+ public void run() throws IOException, SQLException;
1199
1232
  }
1200
1233
 
1201
1234
  protected void withRetry(PluginTask task, IdempotentSqlRunnable op)
@@ -1269,17 +1302,13 @@ public abstract class AbstractJdbcOutputPlugin
1269
1302
  }
1270
1303
  }
1271
1304
 
1272
- public boolean isRetryableException(Exception exception) {
1273
- if (exception instanceof SQLException) {
1274
- SQLException ex = (SQLException)exception;
1275
-
1276
- return AbstractJdbcOutputPlugin.this.isRetryableException(ex);
1277
- } else {
1278
- return false;
1279
- }
1305
+ public boolean isRetryableException(Exception exception)
1306
+ {
1307
+ return AbstractJdbcOutputPlugin.this.isRetryableException(exception);
1280
1308
  }
1281
1309
 
1282
- private String buildExceptionMessage(Throwable ex) {
1310
+ private String buildExceptionMessage(Throwable ex)
1311
+ {
1283
1312
  StringBuilder sb = new StringBuilder();
1284
1313
  sb.append(ex.getMessage());
1285
1314
  if (ex.getCause() != null) {
@@ -1288,7 +1317,8 @@ public abstract class AbstractJdbcOutputPlugin
1288
1317
  return sb.toString();
1289
1318
  }
1290
1319
 
1291
- private void buildExceptionMessageCont(StringBuilder sb, Throwable ex, String lastMessage) {
1320
+ private void buildExceptionMessageCont(StringBuilder sb, Throwable ex, String lastMessage)
1321
+ {
1292
1322
  if (!lastMessage.equals(ex.getMessage())) {
1293
1323
  // suppress same messages
1294
1324
  sb.append(" < ");
@@ -38,6 +38,23 @@ public class JdbcOutputConnection
38
38
  }
39
39
  }
40
40
 
41
+ public void initialize(boolean autoCommit, Optional<TransactionIsolation> transactionIsolation)
42
+ throws SQLException
43
+ {
44
+ connection.setAutoCommit(autoCommit);
45
+
46
+ if (transactionIsolation.isPresent()) {
47
+ connection.setTransactionIsolation(transactionIsolation.get().toInt());
48
+ }
49
+
50
+ try {
51
+ TransactionIsolation currentTransactionIsolation = TransactionIsolation.fromInt(connection.getTransactionIsolation());
52
+ logger.info("TransactionIsolation={}", currentTransactionIsolation.toString());
53
+ } catch (IllegalArgumentException e) {
54
+ logger.info("TransactionIsolation=unknown");
55
+ }
56
+ }
57
+
41
58
  @Override
42
59
  public void close() throws SQLException
43
60
  {
@@ -0,0 +1,63 @@
1
+ package org.embulk.output.jdbc;
2
+
3
+ import org.embulk.spi.Column;
4
+ import org.embulk.spi.time.Timestamp;
5
+ import org.msgpack.value.Value;
6
+
7
+
8
+ public class MemoryRecord implements Record
9
+ {
10
+ private final Object[] values;
11
+
12
+ public MemoryRecord(int columnCount)
13
+ {
14
+ values = new Object[columnCount];
15
+ }
16
+
17
+
18
+ public boolean isNull(Column column)
19
+ {
20
+ return getValue(column) == null;
21
+ }
22
+
23
+ public boolean getBoolean(Column column)
24
+ {
25
+ return (Boolean)getValue(column);
26
+ }
27
+
28
+ public long getLong(Column column)
29
+ {
30
+ return (Long)getValue(column);
31
+ }
32
+
33
+ public double getDouble(Column column)
34
+ {
35
+ return (Double)getValue(column);
36
+ }
37
+
38
+ public String getString(Column column)
39
+ {
40
+ return (String)getValue(column);
41
+ }
42
+
43
+ public Timestamp getTimestamp(Column column)
44
+ {
45
+ return (Timestamp)getValue(column);
46
+ }
47
+
48
+ public Value getJson(Column column)
49
+ {
50
+ return (Value)getValue(column);
51
+ }
52
+
53
+ private Object getValue(Column column)
54
+ {
55
+ return values[column.getIndex()];
56
+ }
57
+
58
+ public void setValue(Column column, Object value)
59
+ {
60
+ values[column.getIndex()] = value;
61
+ }
62
+ }
63
+
@@ -0,0 +1,96 @@
1
+ package org.embulk.output.jdbc;
2
+
3
+ import java.util.ArrayList;
4
+ import java.util.List;
5
+
6
+ import org.embulk.spi.Column;
7
+ import org.embulk.spi.Page;
8
+ import org.embulk.spi.PageReader;
9
+ import org.embulk.spi.time.Timestamp;
10
+ import org.msgpack.value.Value;
11
+
12
+
13
+ /**
14
+ * Record read by PageReader.
15
+ * The class will save read records for retry.
16
+ */
17
+ public class PageReaderRecord implements Record
18
+ {
19
+ private final PageReader pageReader;
20
+ private final List<MemoryRecord> readRecords;
21
+ private MemoryRecord lastRecord;
22
+
23
+ public PageReaderRecord(PageReader pageReader)
24
+ {
25
+ this.pageReader = pageReader;
26
+ readRecords = new ArrayList<MemoryRecord>();
27
+ }
28
+
29
+ public void setPage(Page page)
30
+ {
31
+ pageReader.setPage(page);
32
+ }
33
+
34
+ public boolean nextRecord()
35
+ {
36
+ lastRecord = null; // lastRecord will be created in next `save` method execution.
37
+ return pageReader.nextRecord();
38
+ }
39
+
40
+ public boolean isNull(Column column)
41
+ {
42
+ return pageReader.isNull(column);
43
+ }
44
+
45
+ public boolean getBoolean(Column column)
46
+ {
47
+ return save(column, pageReader.getBoolean(column));
48
+ }
49
+
50
+ public long getLong(Column column)
51
+ {
52
+ return save(column, pageReader.getLong(column));
53
+ }
54
+
55
+ public double getDouble(Column column)
56
+ {
57
+ return save(column, pageReader.getDouble(column));
58
+ }
59
+
60
+ public String getString(Column column)
61
+ {
62
+ return save(column, pageReader.getString(column));
63
+ }
64
+
65
+ public Timestamp getTimestamp(Column column)
66
+ {
67
+ return save(column, pageReader.getTimestamp(column));
68
+ }
69
+
70
+ public Value getJson(Column column)
71
+ {
72
+ return save(column, pageReader.getJson(column));
73
+ }
74
+
75
+ public List<? extends Record> getReadRecords()
76
+ {
77
+ return readRecords;
78
+ }
79
+
80
+ public void clearReadRecords()
81
+ {
82
+ readRecords.clear();
83
+ lastRecord = null;
84
+ }
85
+
86
+ private <T> T save(Column column, T value)
87
+ {
88
+ if (lastRecord == null) {
89
+ lastRecord = new MemoryRecord(pageReader.getSchema().getColumnCount());
90
+ readRecords.add(lastRecord);
91
+ }
92
+ lastRecord.setValue(column, value);
93
+ return value;
94
+ }
95
+ }
96
+
@@ -0,0 +1,23 @@
1
+ package org.embulk.output.jdbc;
2
+
3
+ import org.embulk.spi.Column;
4
+ import org.embulk.spi.time.Timestamp;
5
+ import org.msgpack.value.Value;
6
+
7
+ public interface Record
8
+ {
9
+ boolean isNull(Column column);
10
+
11
+ boolean getBoolean(Column column);
12
+
13
+ long getLong(Column column);
14
+
15
+ double getDouble(Column column);
16
+
17
+ String getString(Column column);
18
+
19
+ Timestamp getTimestamp(Column column);
20
+
21
+ Value getJson(Column column);
22
+ }
23
+
@@ -70,23 +70,27 @@ public class StandardBatchInsert
70
70
 
71
71
  public void flush() throws IOException, SQLException
72
72
  {
73
+ if (batchWeight == 0) return;
74
+
73
75
  logger.info(String.format("Loading %,d rows", batchRows));
74
76
  long startTime = System.currentTimeMillis();
75
- batch.executeBatch(); // here can't use returned value because MySQL Connector/J returns SUCCESS_NO_INFO as a batch result
76
- double seconds = (System.currentTimeMillis() - startTime) / 1000.0;
77
-
78
- totalRows += batchRows;
79
- logger.info(String.format("> %.2f seconds (loaded %,d rows in total)", seconds, totalRows));
80
- batch.clearBatch();
81
- batchRows = 0;
82
- batchWeight = 0;
77
+ try {
78
+ batch.executeBatch(); // here can't use returned value because MySQL Connector/J returns SUCCESS_NO_INFO as a batch result
79
+ double seconds = (System.currentTimeMillis() - startTime) / 1000.0;
80
+
81
+ totalRows += batchRows;
82
+ logger.info(String.format("> %.2f seconds (loaded %,d rows in total)", seconds, totalRows));
83
+
84
+ } finally {
85
+ // clear for retry
86
+ batch.clearBatch();
87
+ batchRows = 0;
88
+ batchWeight = 0;
89
+ }
83
90
  }
84
91
 
85
92
  public void finish() throws IOException, SQLException
86
93
  {
87
- if (getBatchWeight() != 0) {
88
- flush();
89
- }
90
94
  }
91
95
 
92
96
  public void setNull(int sqlType) throws IOException, SQLException
@@ -0,0 +1,66 @@
1
+ package org.embulk.output.jdbc;
2
+
3
+ import java.sql.Connection;
4
+ import java.util.Locale;
5
+
6
+ import org.embulk.config.ConfigException;
7
+
8
+ import com.fasterxml.jackson.annotation.JsonCreator;
9
+ import com.fasterxml.jackson.annotation.JsonValue;
10
+
11
+ public enum TransactionIsolation {
12
+ READ_UNCOMMITTED {
13
+ @Override
14
+ public int toInt() {
15
+ return Connection.TRANSACTION_READ_UNCOMMITTED;
16
+ }
17
+ },
18
+ READ_COMMITTED {
19
+ @Override
20
+ public int toInt() {
21
+ return Connection.TRANSACTION_READ_COMMITTED;
22
+ }
23
+ },
24
+ REPEATABLE_READ {
25
+ @Override
26
+ public int toInt() {
27
+ return Connection.TRANSACTION_REPEATABLE_READ;
28
+ }
29
+ },
30
+ SERIALIZABLE {
31
+ @Override
32
+ public int toInt() {
33
+ return Connection.TRANSACTION_SERIALIZABLE;
34
+ }
35
+ };
36
+
37
+ @JsonValue
38
+ @Override
39
+ public String toString()
40
+ {
41
+ return name().toLowerCase(Locale.ENGLISH);
42
+ }
43
+
44
+ public abstract int toInt();
45
+
46
+ @JsonCreator
47
+ public static TransactionIsolation fromString(String value)
48
+ {
49
+ for (TransactionIsolation ti : values()) {
50
+ if (ti.toString().equals(value)) {
51
+ return ti;
52
+ }
53
+ }
54
+ throw new ConfigException(String.format("Unknown transaction_isolation '%s'.", value));
55
+ }
56
+
57
+ public static TransactionIsolation fromInt(int value)
58
+ {
59
+ for (TransactionIsolation ti : values()) {
60
+ if (ti.toInt() == value) {
61
+ return ti;
62
+ }
63
+ }
64
+ throw new IllegalArgumentException(String.format("Unknown transaction_isolation '%d'.", value));
65
+ }
66
+ }
@@ -2,19 +2,20 @@ package org.embulk.output.jdbc.setter;
2
2
 
3
3
  import java.io.IOException;
4
4
  import java.sql.SQLException;
5
+
6
+ import org.embulk.output.jdbc.Record;
5
7
  import org.embulk.spi.Column;
6
8
  import org.embulk.spi.ColumnVisitor;
7
- import org.embulk.spi.PageReader;
8
9
 
9
10
  public class ColumnSetterVisitor
10
11
  implements ColumnVisitor
11
12
  {
12
- private final PageReader pageReader;
13
+ private final Record record;
13
14
  private final ColumnSetter setter;
14
15
 
15
- public ColumnSetterVisitor(PageReader pageReader, ColumnSetter setter)
16
+ public ColumnSetterVisitor(Record record, ColumnSetter setter)
16
17
  {
17
- this.pageReader = pageReader;
18
+ this.record = record;
18
19
  this.setter = setter;
19
20
  }
20
21
 
@@ -22,10 +23,10 @@ public class ColumnSetterVisitor
22
23
  public void booleanColumn(Column column)
23
24
  {
24
25
  try {
25
- if (pageReader.isNull(column)) {
26
+ if (record.isNull(column)) {
26
27
  setter.nullValue();
27
28
  } else {
28
- setter.booleanValue(pageReader.getBoolean(column));
29
+ setter.booleanValue(record.getBoolean(column));
29
30
  }
30
31
  } catch (IOException | SQLException ex) {
31
32
  // TODO exception class
@@ -37,10 +38,10 @@ public class ColumnSetterVisitor
37
38
  public void longColumn(Column column)
38
39
  {
39
40
  try {
40
- if (pageReader.isNull(column)) {
41
+ if (record.isNull(column)) {
41
42
  setter.nullValue();
42
43
  } else {
43
- setter.longValue(pageReader.getLong(column));
44
+ setter.longValue(record.getLong(column));
44
45
  }
45
46
  } catch (IOException | SQLException ex) {
46
47
  // TODO exception class
@@ -52,10 +53,10 @@ public class ColumnSetterVisitor
52
53
  public void doubleColumn(Column column)
53
54
  {
54
55
  try {
55
- if (pageReader.isNull(column)) {
56
+ if (record.isNull(column)) {
56
57
  setter.nullValue();
57
58
  } else {
58
- setter.doubleValue(pageReader.getDouble(column));
59
+ setter.doubleValue(record.getDouble(column));
59
60
  }
60
61
  } catch (IOException | SQLException ex) {
61
62
  // TODO exception class
@@ -67,10 +68,10 @@ public class ColumnSetterVisitor
67
68
  public void stringColumn(Column column)
68
69
  {
69
70
  try {
70
- if (pageReader.isNull(column)) {
71
+ if (record.isNull(column)) {
71
72
  setter.nullValue();
72
73
  } else {
73
- setter.stringValue(pageReader.getString(column));
74
+ setter.stringValue(record.getString(column));
74
75
  }
75
76
  } catch (IOException | SQLException ex) {
76
77
  // TODO exception class
@@ -82,10 +83,10 @@ public class ColumnSetterVisitor
82
83
  public void jsonColumn(Column column)
83
84
  {
84
85
  try {
85
- if (pageReader.isNull(column)) {
86
+ if (record.isNull(column)) {
86
87
  setter.nullValue();
87
88
  } else {
88
- setter.jsonValue(pageReader.getJson(column));
89
+ setter.jsonValue(record.getJson(column));
89
90
  }
90
91
  } catch (IOException | SQLException ex) {
91
92
  // TODO exception class
@@ -97,10 +98,10 @@ public class ColumnSetterVisitor
97
98
  public void timestampColumn(Column column)
98
99
  {
99
100
  try {
100
- if (pageReader.isNull(column)) {
101
+ if (record.isNull(column)) {
101
102
  setter.nullValue();
102
103
  } else {
103
- setter.timestampValue(pageReader.getTimestamp(column));
104
+ setter.timestampValue(record.getTimestamp(column));
104
105
  }
105
106
  } catch (IOException | SQLException ex) {
106
107
  // TODO exception class
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.8.2
4
+ version: 0.8.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sadayuki Furuhashi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-01-30 00:00:00.000000000 Z
11
+ date: 2019-05-07 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Inserts or updates records to a table.
14
14
  email:
@@ -19,9 +19,10 @@ extra_rdoc_files: []
19
19
  files:
20
20
  - README.md
21
21
  - build.gradle
22
- - classpath/embulk-output-jdbc-0.8.2.jar
22
+ - classpath/embulk-output-jdbc-0.8.3.jar
23
23
  - lib/embulk/output/jdbc.rb
24
24
  - src/main/java/org/embulk/output/JdbcOutputPlugin.java
25
+ - src/main/java/org/embulk/output/jdbc/AbstractJdbcOutputConnector.java
25
26
  - src/main/java/org/embulk/output/jdbc/AbstractJdbcOutputPlugin.java
26
27
  - src/main/java/org/embulk/output/jdbc/BatchInsert.java
27
28
  - src/main/java/org/embulk/output/jdbc/JdbcColumn.java
@@ -30,13 +31,17 @@ files:
30
31
  - src/main/java/org/embulk/output/jdbc/JdbcOutputConnector.java
31
32
  - src/main/java/org/embulk/output/jdbc/JdbcSchema.java
32
33
  - src/main/java/org/embulk/output/jdbc/JdbcUtils.java
34
+ - src/main/java/org/embulk/output/jdbc/MemoryRecord.java
33
35
  - src/main/java/org/embulk/output/jdbc/MergeConfig.java
36
+ - src/main/java/org/embulk/output/jdbc/PageReaderRecord.java
37
+ - src/main/java/org/embulk/output/jdbc/Record.java
34
38
  - src/main/java/org/embulk/output/jdbc/Ssl.java
35
39
  - src/main/java/org/embulk/output/jdbc/StandardBatchInsert.java
36
40
  - src/main/java/org/embulk/output/jdbc/TableIdentifier.java
37
41
  - src/main/java/org/embulk/output/jdbc/TimestampFormat.java
38
42
  - src/main/java/org/embulk/output/jdbc/ToString.java
39
43
  - src/main/java/org/embulk/output/jdbc/ToStringMap.java
44
+ - src/main/java/org/embulk/output/jdbc/TransactionIsolation.java
40
45
  - src/main/java/org/embulk/output/jdbc/setter/BigDecimalColumnSetter.java
41
46
  - src/main/java/org/embulk/output/jdbc/setter/BooleanColumnSetter.java
42
47
  - src/main/java/org/embulk/output/jdbc/setter/ByteColumnSetter.java